Skip to content

Commit

Permalink
Merge pull request #199 from planetarium/release/0.8.0
Browse files Browse the repository at this point in the history
Release/0.8.0
  • Loading branch information
U-lis authored Dec 13, 2023
2 parents 984adf5 + ecccca4 commit ebf7473
Show file tree
Hide file tree
Showing 28 changed files with 909 additions and 325 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,22 @@ on:
required: true
IAP_GARAGE_WEBHOOK_URL:
required: true
IAP_ALERT_WEBHOOK_URL:
required: true
GOLDEN_DUST_REQUEST_SHEET_ID:
required: true
GOLDEN_DUST_WORK_SHEET_ID:
required: true
SEASON_PASS_JWT_SECRET:
required: true
VOUCHER_URL:
required: true
VOUCHER_JWT_SECRET:
required: true
BRIDGE_DATA:
required: true
REFUND_SHEET_ID:
required: true

jobs:
deployment:
Expand Down Expand Up @@ -131,13 +139,17 @@ jobs:
APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
IAP_GARAGE_WEBHOOK_URL: ${{ secrets.IAP_GARAGE_WEBHOOK_URL }}
IAP_ALERT_WEBHOOK_URL: ${{ secrets.IAP_ALERT_WEBHOOK_URL }}
GOLDEN_DUST_REQUEST_SHEET_ID: ${{ secrets.GOLDEN_DUST_REQUEST_SHEET_ID }}
GOLDEN_DUST_WORK_SHEET_ID: ${{ secrets.GOLDEN_DUST_WORK_SHEET_ID }}
FORM_SHEET: ${{ vars.FORM_SHEET }}
CDN_HOST: ${{ vars.CDN_HOST }}
PLANET_URL: ${{ vars.PLANET_URL }}
SEASON_PASS_JWT_SECRET: ${{ secrets.SEASON_PASS_JWT_SECRET }}
VOUCHER_URL: ${{ secrets.VOUCHER_URL }}
VOUCHER_JWT_SECRET: ${{ secrets.VOUCHER_JWT_SECRET }}
BRIDGE_DATA: ${{ secrets.BRIDGE_DATA }}
REFUND_SHEET_ID : ${{ secrets.REFUND_SHEET_ID }}
run: |
source $VENV
yarn cdk synth
Expand All @@ -160,13 +172,17 @@ jobs:
APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
IAP_GARAGE_WEBHOOK_URL: ${{ secrets.IAP_GARAGE_WEBHOOK_URL }}
IAP_ALERT_WEBHOOK_URL: ${{ secrets.IAP_ALERT_WEBHOOK_URL }}
GOLDEN_DUST_REQUEST_SHEET_ID: ${{ secrets.GOLDEN_DUST_REQUEST_SHEET_ID }}
GOLDEN_DUST_WORK_SHEET_ID: ${{ secrets.GOLDEN_DUST_WORK_SHEET_ID }}
FORM_SHEET: ${{ vars.FORM_SHEET }}
CDN_HOST: ${{ vars.CDN_HOST }}
PLANET_URL: ${{ vars.PLANET_URL }}
SEASON_PASS_JWT_SECRET: ${{ secrets.SEASON_PASS_JWT_SECRET }}
VOUCHER_URL: ${{ secrets.VOUCHER_URL }}
VOUCHER_JWT_SECRET: ${{ secrets.VOUCHER_JWT_SECRET }}
BRIDGE_DATA: ${{ secrets.BRIDGE_DATA }}
REFUND_SHEET_ID : ${{ secrets.REFUND_SHEET_ID }}
run: |
source $VENV
yarn cdk deploy --all --require-approval never -O output.txt
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,14 @@ jobs:
APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
IAP_GARAGE_WEBHOOK_URL: ${{ secrets.IAP_GARAGE_WEBHOOK_URL }}
IAP_ALERT_WEBHOOK_URL: ${{ secrets.IAP_ALERT_WEBHOOK_URL }}
GOLDEN_DUST_REQUEST_SHEET_ID: ${{ secrets.GOLDEN_DUST_REQUEST_SHEET_ID }}
GOLDEN_DUST_WORK_SHEET_ID: ${{ secrets.GOLDEN_DUST_WORK_SHEET_ID }}
SEASON_PASS_JWT_SECRET: ${{ secrets.SEASON_PASS_JWT_SECRET }}
VOUCHER_URL: ${{ secrets.VOUCHER_URL }}
VOUCHER_JWT_SECRET: ${{ secrets.VOUCHER_JWT_SECRET }}
BRIDGE_DATA: ${{ secrets.BRIDGE_DATA }}
REFUND_SHEET_ID : ${{ secrets.REFUND_SHEET_ID }}

deploy_without_approval:
# This is for development / internal deployment
Expand All @@ -65,10 +69,14 @@ jobs:
APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
IAP_GARAGE_WEBHOOK_URL: ${{ secrets.IAP_GARAGE_WEBHOOK_URL }}
IAP_ALERT_WEBHOOK_URL: ${{ secrets.IAP_ALERT_WEBHOOK_URL }}
GOLDEN_DUST_REQUEST_SHEET_ID: ${{ secrets.GOLDEN_DUST_REQUEST_SHEET_ID }}
GOLDEN_DUST_WORK_SHEET_ID: ${{ secrets.GOLDEN_DUST_WORK_SHEET_ID }}
SEASON_PASS_JWT_SECRET: ${{ secrets.SEASON_PASS_JWT_SECRET }}
VOUCHER_URL: ${{ secrets.VOUCHER_URL }}
VOUCHER_JWT_SECRET: ${{ secrets.VOUCHER_JWT_SECRET }}
BRIDGE_DATA: ${{ secrets.BRIDGE_DATA }}
REFUND_SHEET_ID : ${{ secrets.REFUND_SHEET_ID }}

approval:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -100,7 +108,11 @@ jobs:
APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
IAP_GARAGE_WEBHOOK_URL: ${{ secrets.IAP_GARAGE_WEBHOOK_URL }}
IAP_ALERT_WEBHOOK_URL: ${{ secrets.IAP_ALERT_WEBHOOK_URL }}
GOLDEN_DUST_REQUEST_SHEET_ID: ${{ secrets.GOLDEN_DUST_REQUEST_SHEET_ID }}
GOLDEN_DUST_WORK_SHEET_ID: ${{ secrets.GOLDEN_DUST_WORK_SHEET_ID }}
SEASON_PASS_JWT_SECRET: ${{ secrets.SEASON_PASS_JWT_SECRET }}
VOUCHER_URL: ${{ secrets.VOUCHER_URL }}
VOUCHER_JWT_SECRET: ${{ secrets.VOUCHER_JWT_SECRET }}
BRIDGE_DATA: ${{ secrets.BRIDGE_DATA }}
REFUND_SHEET_ID : ${{ secrets.REFUND_SHEET_ID }}
12 changes: 12 additions & 0 deletions .github/workflows/synth.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,22 @@ on:
required: true
IAP_GARAGE_WEBHOOK_URL:
required: true
IAP_ALERT_WEBHOOK_URL:
required: true
GOLDEN_DUST_REQUEST_SHEET_ID:
required: true
GOLDEN_DUST_WORK_SHEET_ID:
required: true
SEASON_PASS_JWT_SECRET:
required: true
VOUCHER_URL:
required: true
VOUCHER_JWT_SECRET:
required: true
BRIDGE_DATA:
required: true
REFUND_SHEET_ID:
required: true

jobs:
synth:
Expand Down Expand Up @@ -118,13 +126,17 @@ jobs:
APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
IAP_GARAGE_WEBHOOK_URL: ${{ secrets.IAP_GARAGE_WEBHOOK_URL }}
IAP_ALERT_WEBHOOK_URL: ${{ secrets.IAP_ALERT_WEBHOOK_URL }}
GOLDEN_DUST_REQUEST_SHEET_ID: ${{ secrets.GOLDEN_DUST_REQUEST_SHEET_ID }}
GOLDEN_DUST_WORK_SHEET_ID: ${{ secrets.GOLDEN_DUST_WORK_SHEET_ID }}
FORM_SHEET: ${{ vars.FORM_SHEET }}
CDN_HOST: ${{ vars.CDN_HOST }}
PLANET_URL: ${{ vars.PLANET_URL }}
SEASON_PASS_JWT_SECRET: ${{ secrets.SEASON_PASS_JWT_SECRET }}
VOUCHER_URL: ${{ secrets.VOUCHER_URL }}
VOUCHER_JWT_SECRET: ${{ secrets.VOUCHER_JWT_SECRET }}
BRIDGE_DATA: ${{ secrets.BRIDGE_DATA }}
REFUND_SHEET_ID : ${{ secrets.REFUND_SHEET_ID }}
run: |
source $VENV
yarn cdk synth
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
- name: Run test
run: |
poetry run pytest tests/utils
poetry run pytest tests
slack_notification:
uses: ./.github/workflows/slack_message.yml
Expand Down
8 changes: 8 additions & 0 deletions common/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,13 @@ class Config:
golden_dust_work_sheet_id: Optional[str] = None
form_sheet: Optional[str] = None

# Status monitor
iap_garage_webhook_url: str = None
iap_alert_webhook_url: str = None

# SeasonPass
season_pass_jwt_secret: str = None

# Voucher
voucher_url: str = None
voucher_jwt_secret: str = None
28 changes: 28 additions & 0 deletions common/alembic/versions/2822c456abc3_add_unique_constraint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""Add unique constraint
Revision ID: 2822c456abc3
Revises: 5bf8ab4f3b13
Create Date: 2023-12-05 01:11:38.405536
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = '2822c456abc3'
down_revision = '5bf8ab4f3b13'
branch_labels = None
depends_on = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_unique_constraint("voucher_request_receipt_id_unique", 'voucher_request', ['receipt_id'])
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint("voucher_request_receipt_id_unique", 'voucher_request', type_='unique')
# ### end Alembic commands ###
46 changes: 46 additions & 0 deletions common/alembic/versions/5bf8ab4f3b13_add_voucher_request_table.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""Add voucher_request table
Revision ID: 5bf8ab4f3b13
Revises: 57e65ed34bd6
Create Date: 2023-12-01 11:22:16.116276
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = '5bf8ab4f3b13'
down_revision = '57e65ed34bd6'
branch_labels = None
depends_on = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('voucher_request',
sa.Column('receipt_id', sa.Integer(), nullable=False),
sa.Column('uuid', sa.UUID(), nullable=False),
sa.Column('agent_addr', sa.Text(), nullable=False),
sa.Column('avatar_addr', sa.Text(), nullable=False),
sa.Column('planet_id', sa.LargeBinary(length=12), nullable=False),
sa.Column('product_id', sa.Integer(), nullable=False),
sa.Column('product_name', sa.Text(), nullable=False),
sa.Column('status', sa.Integer(), nullable=True),
sa.Column('message', sa.Text(), nullable=True),
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
sa.ForeignKeyConstraint(['product_id'], ['product.id'], ),
sa.ForeignKeyConstraint(['receipt_id'], ['receipt.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_voucher_request_uuid'), 'voucher_request', ['uuid'], unique=False)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_voucher_request_uuid'), table_name='voucher_request')
op.drop_table('voucher_request')
# ### end Alembic commands ###
1 change: 1 addition & 0 deletions common/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
"garage",
"receipt",
"product",
"voucher",
]
2 changes: 1 addition & 1 deletion common/models/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class Category(AutoIdMixin, TimeStampMixin, Base):
# FIXME: Update to nullable=False
l10n_key = Column(Text, doc="L10N Key")

product_list: Mapped[List["Product"]] = relationship("Product", secondary=category_product_table)
product_list: Mapped[List["Product"]] = relationship("Product", secondary=category_product_table, order_by="Product.order")

@property
def path(self):
Expand Down
31 changes: 31 additions & 0 deletions common/models/voucher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import uuid

from sqlalchemy import Column, Text, Integer, ForeignKey, UUID, LargeBinary
from sqlalchemy.orm import relationship, backref, Mapped

from common.models.base import Base, TimeStampMixin, AutoIdMixin
from common.models.product import Product
from common.models.receipt import Receipt
from common.utils.receipt import PlanetID


class VoucherRequest(AutoIdMixin, TimeStampMixin, Base):
__tablename__ = "voucher_request"
receipt_id = Column(Integer, ForeignKey("receipt.id"), nullable=False, unique=True)
receipt: Mapped["Receipt"] = relationship("Receipt", foreign_keys=[receipt_id], uselist=False,
backref=backref("voucher_request"))

# Copy all required data to view all info solely with this table
uuid = Column(UUID(as_uuid=True), nullable=False, index=True, default=uuid.uuid4,
doc="Internal uuid for management")
agent_addr = Column(Text, nullable=False)
avatar_addr = Column(Text, nullable=False)
planet_id = Column(LargeBinary(length=12), nullable=False, default=PlanetID.ODIN.value,
doc="An identifier of planets")
product_id = Column(Integer, ForeignKey("product.id"), nullable=False)
product: Mapped["Product"] = relationship("Product", foreign_keys=[product_id], uselist=False)
product_name = Column(Text, nullable=False)

# Voucher request result
status = Column(Integer, nullable=True)
message = Column(Text, nullable=True)
10 changes: 9 additions & 1 deletion common/shared_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
visibility_timeout=cdk_core.Duration.seconds(20),
)

self.voucher_dlq = _sqs.Queue(self, f"{config.stage}-9c-iap-voucher-dlq")
self.voucher_q = _sqs.Queue(
self, f"{config.stage}-9c-iap-voucher-queue",
dead_letter_queue=_sqs.DeadLetterQueue(max_receive_count=10, queue=self.voucher_dlq),
visibility_timeout=cdk_core.Duration.seconds(30),
)

# RDS
self.rds_security_group = _ec2.SecurityGroup(
self, f"{config.stage}-9c-iap-rds-sg", vpc=self.vpc, allow_all_outbound=True
Expand Down Expand Up @@ -89,7 +96,8 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
("KMS_KEY_ID", True),
("GOOGLE_CREDENTIAL", True),
("APPLE_CREDENTIAL", True),
("SEASON_PASS_JWT_SECRET", True)
("SEASON_PASS_JWT_SECRET", True),
("VOUCHER_JWT_SECRET", True),
)
ssm = boto3.client("ssm", region_name=config.region_name,
aws_access_key_id=os.environ.get("AWS_ACCESS_KEY_ID"),
Expand Down
32 changes: 6 additions & 26 deletions iap/api/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

from common.models.product import Product, Category
from common.utils.address import format_addr
from common.utils.garage import get_iap_garage
from common.utils.receipt import PlanetID
from iap import settings
from iap.dependencies import session
Expand Down Expand Up @@ -38,17 +37,6 @@ def product_list(agent_addr: str,
.order_by(Category.order, Product.order)
).all()

iap_garage = {x.fungible_id: x.amount for x in get_iap_garage(sess)}
garage = {}
for category in all_category_list:
if ((category.open_timestamp and category.open_timestamp > datetime.now()) or
(category.close_timestamp and category.close_timestamp <= datetime.now())):
continue

for product in category.product_list:
for fungible_item in product.fungible_item_list:
garage[fungible_item.fungible_item_id] = iap_garage.get(fungible_item.fungible_item_id, 0)

category_schema_list = []
for category in all_category_list:
cat_schema = CategorySchema.model_validate(category)
Expand All @@ -59,21 +47,8 @@ def product_list(agent_addr: str,
(product.close_timestamp and product.close_timestamp <= datetime.now())):
continue

schema_dict[product.id] = ProductSchema.model_validate(product)
# FIXME: Pinpoint get product buyability
product_buyable = True
# Check fungible item stock in garage
for item in product.fungible_item_list:
if garage.get(item.fungible_item_id, 0) < item.amount:
schema_dict[product.id].buyable = False
product_buyable = False
break

if not product_buyable:
continue

# Check purchase history
schema = schema_dict[product.id]
schema = ProductSchema.model_validate(product)
if product.daily_limit:
schema.purchase_count = get_purchase_count(
sess, product.id, planet_id=planet_id, agent_addr=agent_addr, daily_limit=True
Expand All @@ -89,6 +64,11 @@ def product_list(agent_addr: str,
sess, product.id, planet_id=planet_id, agent_addr=agent_addr
)
schema.buyable = schema.purchase_count < product.account_limit
else: # Product with no limitation
schema.buyable = True

schema_dict[product.id] = schema

cat_schema.product_list = list(schema_dict.values())
category_schema_list.append(cat_schema)

Expand Down
Loading

0 comments on commit ebf7473

Please sign in to comment.