Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions src/.env
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ DOCKER_IMAGE_FRONTEND=pom_frontend

# Backend
PRIVATIZE_API=
TESTING=True
TESTING=
RATE_LIMIT=
BACKEND_CORS_ORIGINS="http://localhost,http://localhost:5173,http://localhost:5174,https://localhost,https://localhost:5173,https://localhost:5174"
PROJECT_NAME="pathofmodifiers"
Expand All @@ -35,20 +35,15 @@ SMTP_USER=noreply@pathofmodifiers.com
SMTP_PASSWORD=changethis
TURNSTILE_SECRET_KEY=1x0000000000000000000000000000000AA

# League
CURRENT_SOFTCORE_LEAGUE="Mirage"
ALL_SOFTCORE_LEAGUES="Mirage|Keepers|Mercenaries|Phrecia"

LEAGUE_LAUNCH_TIME=2026-03-06T19:00:00Z # ISO 8601 format. Round backwards to whole hour number

# Data retrieval
MANUAL_NEXT_CHANGE_ID=True
# Change ID Retrieved 02.09.2024:
NEXT_CHANGE_ID=2621291179-2592930469-2516326916-2790039644-2710714910
# Change ID Retrieved 28.06.2026:
NEXT_CHANGE_ID=3176140940-3103957281-3029294684-3370770619-3261964453
POE_PUBLIC_STASHES_AUTH_TOKEN=changethis
# Enables the public stashes creation script in data_ret/app/tests/scripts.
# Set value "True" to activate:
DATA_RET_TEST_PUB_STASH_SIM_DATA_DEPOSIT_ENABLED=True
DATA_RET_TEST_PUB_STASH_SIM_DATA_DEPOSIT_ENABLED=

# Postgres
POSTGRES_PORT=5432
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
"""Added league table

Revision ID: 965e766db0a0
Revises: 17daa1c96438
Create Date: 2026-06-30 15:49:45.173827

"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa

from app.alembic.replaceable_objects.main import ReplaceableTrigger

# revision identifiers, used by Alembic.
revision: str = "965e766db0a0"
down_revision: Union[str, None] = "17daa1c96438"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None

unidentified_aggregation_trigger_old = ReplaceableTrigger(
"aggregate_unidentified",
"unidentified_item",
"""
RETURNS TRIGGER AS ${name}$
DECLARE
current_hour INT;
divine_id INT;
divine_value FLOAT;
BEGIN
IF EXISTS (SELECT 1 FROM unidentified_item AS unid WHERE unid."createdHoursSinceLaunch" = NEW."createdHoursSinceLaunch") THEN
RETURN NEW;
END IF;

current_hour := (SELECT MAX(unid."createdHoursSinceLaunch") FROM unidentified_item AS unid);
divine_id := (SELECT MAX(cur."currencyId") FROM currency AS cur WHERE cur."tradeName"='divine');
divine_value := (SELECT cur."valueInChaos" FROM currency AS cur WHERE cur."currencyId"=divine_id);


WITH aggregates AS (
SELECT name, unid."itemBaseTypeId", unid."createdHoursSinceLaunch", league, ilvl, stddev(unid."currencyAmount" * cur."valueInChaos") AS std, AVG(unid."currencyAmount" * cur."valueInChaos") AS calc_avg, COUNT(unid."itemId") AS calc_count
FROM unidentified_item AS unid
NATURAL JOIN currency as cur
WHERE unid."createdHoursSinceLaunch" = current_hour
AND NOT aggregated
GROUP BY name, unid."itemBaseTypeId", unid."createdHoursSinceLaunch", league, ilvl
), affected_item_ids AS (
SELECT unid."itemId" FROM unidentified_item AS unid WHERE NOT aggregated AND unid."createdHoursSinceLaunch"=current_hour
)

INSERT INTO unidentified_item (name, "itemBaseTypeId", "createdHoursSinceLaunch", league, "currencyId", ilvl, "currencyAmount", "nItems", identified, rarity, aggregated)
SELECT name, unid."itemBaseTypeId", unid."createdHoursSinceLaunch", league, divine_id, ilvl, AVG(unid."currencyAmount" * cur."valueInChaos") / divine_value, calc_count, identified, rarity, TRUE
FROM unidentified_item AS unid
NATURAL JOIN aggregates
NATURAL JOIN currency AS cur
WHERE unid."currencyAmount" * cur."valueInChaos" <= calc_avg + 1.97 * std
AND unid."currencyAmount" * cur."valueInChaos" >= calc_avg - 1.97 * std
GROUP BY name, unid."itemBaseTypeId", unid."createdHoursSinceLaunch", league, ilvl, identified, rarity, calc_count;

DELETE FROM unidentified_item as unid
WHERE NOT aggregated AND unid."createdHoursSinceLaunch"=current_hour;

RETURN NEW;
END;
${name}$ LANGUAGE plpgsql;
""",
"""
BEFORE INSERT ON {table}
FOR EACH ROW
EXECUTE FUNCTION {name}();
""",
)


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"league",
sa.Column(
"leagueId", sa.SmallInteger(), sa.Identity(always=False), nullable=False
),
sa.Column("name", sa.Text(), nullable=False),
sa.Column("validFrom", sa.DateTime(timezone=True), nullable=False),
sa.Column("validTo", sa.DateTime(timezone=True), nullable=True),
sa.Column("version", sa.Float(), nullable=False),
sa.PrimaryKeyConstraint("leagueId"),
)
op.execute("""
Comment thread
bogadisa marked this conversation as resolved.
INSERT INTO league (name, "validFrom", version)
SELECT DISTINCT
league,
TIMESTAMP '1970-01-01 00:00:00',
0.0
FROM item
WHERE league IS NOT NULL
""")

# ---- Item table ----
op.add_column("item", sa.Column("leagueId", sa.SmallInteger()))
op.execute("""
UPDATE item
SET "leagueId" = l."leagueId"
FROM league l
WHERE item.league = l.name
""")
op.alter_column("item", "leagueId", nullable=False)
op.create_foreign_key(
"fk_item_league",
"item",
"league",
["leagueId"],
["leagueId"],
ondelete="RESTRICT",
onupdate="CASCADE",
)
op.drop_column("item", "league")

# ---- Unidentified item table ----
op.add_column("unidentified_item", sa.Column("leagueId", sa.SmallInteger()))
op.execute("""
UPDATE unidentified_item
SET "leagueId" = l."leagueId"
FROM league l
WHERE league = l.name
""")
op.alter_column("unidentified_item", "leagueId", nullable=False)
op.create_foreign_key(
"fk_unidentified_item_league",
"unidentified_item",
"league",
["leagueId"],
["leagueId"],
ondelete="RESTRICT",
onupdate="CASCADE",
)
op.drop_column("unidentified_item", "league")

# ---- Currency table ----
op.add_column("currency", sa.Column("leagueId", sa.SmallInteger()))
# Deletes all currency ids that are not used
op.execute("""
DELETE FROM currency c
WHERE NOT EXISTS (
SELECT 1
FROM item i
WHERE i."currencyId" = c."currencyId"
)
""")
op.execute("""
UPDATE currency c
SET "leagueId" = i.leagueId
FROM (
SELECT item."currencyId", MIN(item."leagueId") AS leagueId
FROM item
GROUP BY item."currencyId"
) i
WHERE c."currencyId" = i."currencyId"
""")
op.alter_column("currency", "leagueId", nullable=False)
op.create_foreign_key(
"fk_currency_league",
"currency",
"league",
["leagueId"],
["leagueId"],
ondelete="RESTRICT",
onupdate="CASCADE",
)

# ---- Indexes ----
# Manual SQL to drop query instead of `op.drop_index` is needed due to hypertables
op.execute("""
DROP INDEX IF EXISTS ix_item_name_itemBaseTypeId_createdHoursSinceLaunch_league
""")
op.create_index(
"ix_item_name_itemBaseTypeId_createdHoursSinceLaunch_leagueId",
"item",
[
"name",
"itemBaseTypeId",
"createdHoursSinceLaunch",
"leagueId",
],
unique=False,
)

op.execute("""
DROP INDEX IF EXISTS ix_unid_item_name_itemBaseTypeId_createdHoursSinceLaunch_league
""")
op.create_index(
"ix_unid_name_itemBaseTypeId_createdHoursSinceLaunch_leagueId",
"unidentified_item",
[
"name",
"itemBaseTypeId",
"createdHoursSinceLaunch",
"leagueId",
],
unique=False,
)

# ---- triggers ----
op.drop_trigger(unidentified_aggregation_trigger_old)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
# ---- Item table ----
op.add_column(
"item",
sa.Column("league", sa.TEXT(), autoincrement=False),
)
op.execute("""
UPDATE item i
SET league = l.name
FROM league l
WHERE i."leagueId" = l."leagueId"
""")
op.alter_column("item", "league", nullable=False)
op.drop_constraint("fk_item_league", "item", type_="foreignkey")
op.execute("""
DROP INDEX IF EXISTS ix_item_name_itemBaseTypeId_createdHoursSinceLaunch_leagueId
""")
op.create_index(
"ix_item_name_itemBaseTypeId_createdHoursSinceLaunch_league",
"item",
["name", "itemBaseTypeId", "createdHoursSinceLaunch", "league"],
unique=False,
)
op.drop_column("item", "leagueId")

# ---- Unidentified item table ----
op.add_column(
"unidentified_item",
sa.Column("league", sa.TEXT(), autoincrement=False),
)
op.execute("""
UPDATE unidentified_item ui
SET league = l.name
FROM league l
WHERE ui."leagueId" = l."leagueId"
""")
op.alter_column("unidentified_item", "league", nullable=False)
op.drop_constraint(
"fk_unidentified_item_league", "unidentified_item", type_="foreignkey"
)
op.execute("""
DROP INDEX IF EXISTS ix_unid_name_itemBaseTypeId_createdHoursSinceLaunch_leagueId
""")
op.create_index(
"ix_unid_item_name_itemBaseTypeId_createdHoursSinceLaunch_league",
"unidentified_item",
["name", "itemBaseTypeId", "createdHoursSinceLaunch", "league"],
unique=False,
)
op.drop_column("unidentified_item", "leagueId")

# ---- Currency table ----
op.drop_column("currency", "leagueId")

op.drop_table("league")

# ---- triggers ----
op.create_trigger(unidentified_aggregation_trigger_old)
# ### end Alembic commands ###
Loading
Loading