commit 651703c0f8a21ab1963039be116620bf9be35ba2 Author: juyoungk09 Date: Wed Jul 9 09:16:59 2025 +0900 initial test diff --git a/__pycache__/app.cpython-313.pyc b/__pycache__/app.cpython-313.pyc new file mode 100644 index 0000000..e9f29bc Binary files /dev/null and b/__pycache__/app.cpython-313.pyc differ diff --git a/__pycache__/db.cpython-313.pyc b/__pycache__/db.cpython-313.pyc new file mode 100644 index 0000000..4b88d78 Binary files /dev/null and b/__pycache__/db.cpython-313.pyc differ diff --git a/app.py b/app.py new file mode 100644 index 0000000..3ef3afb --- /dev/null +++ b/app.py @@ -0,0 +1,20 @@ +from flask import Flask +from routes import add_namespaces +from flask_restx import Api +from db import db +from flask_migrate import Migrate + +app = Flask(__name__) +app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///dotori.db' +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False + +db.init_app(app) +migrate = Migrate(app, db) + +with app.app_context(): + db.create_all() + +api = Api(app, doc='/docs') +add_namespaces(api) +if __name__ == '__main__': + app.run(debug=True) diff --git a/db.py b/db.py new file mode 100644 index 0000000..2e1eeb6 --- /dev/null +++ b/db.py @@ -0,0 +1,3 @@ +from flask_sqlalchemy import SQLAlchemy + +db = SQLAlchemy() \ No newline at end of file diff --git a/instance/dotori.db b/instance/dotori.db new file mode 100644 index 0000000..f07a16f Binary files /dev/null and b/instance/dotori.db differ diff --git a/models/__pycache__/dotori.cpython-313.pyc b/models/__pycache__/dotori.cpython-313.pyc new file mode 100644 index 0000000..97ebce8 Binary files /dev/null and b/models/__pycache__/dotori.cpython-313.pyc differ diff --git a/models/dotori.py b/models/dotori.py new file mode 100644 index 0000000..9d0564f --- /dev/null +++ b/models/dotori.py @@ -0,0 +1,41 @@ +from flask_sqlalchemy import SQLAlchemy +from datetime import datetime +from db import db + +class UserDotori(db.Model): + __tablename__ = 'user_dotori' + + id = db.Column(db.Integer, primary_key=True) + user_id = db.Column(db.String(100), unique=True, nullable=False) + dotori_count = db.Column(db.Integer, default=0) + created_at = db.Column(db.DateTime, default=datetime.now) + updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now) + + def to_dict(self): + return { + 'id': self.id, + 'user_id': self.user_id, + 'dotori_count': self.dotori_count, + 'created_at': self.created_at.isoformat(), + 'updated_at': self.updated_at.isoformat() + } + + def to_response(self): + return { + 'userId': self.user_id, + 'dotory': self.dotori_count + } + + def increment(self, amount=1): + self.dotori_count += amount + self.updated_at = datetime.now() + return self.dotori_count + + def decrement(self, amount=1): + if self.dotori_count >= amount: + self.dotori_count -= amount + self.updated_at = datetime.now() + return self.dotori_count + return False + def __repr__(self): + return f"" \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..0cad80d Binary files /dev/null and b/requirements.txt differ diff --git a/routes/__init__.py b/routes/__init__.py new file mode 100644 index 0000000..b787db0 --- /dev/null +++ b/routes/__init__.py @@ -0,0 +1,8 @@ +from flask_restx import Api + +from .dotori import dotori_ns +from .product import product_ns + +def add_namespaces(api): + api.add_namespace(dotori_ns, path='/api/dotory') + api.add_namespace(product_ns, path='/api/buy') \ No newline at end of file diff --git a/routes/__pycache__/__init__.cpython-313.pyc b/routes/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..bf29d98 Binary files /dev/null and b/routes/__pycache__/__init__.cpython-313.pyc differ diff --git a/routes/__pycache__/buy.cpython-313.pyc b/routes/__pycache__/buy.cpython-313.pyc new file mode 100644 index 0000000..f0bef4c Binary files /dev/null and b/routes/__pycache__/buy.cpython-313.pyc differ diff --git a/routes/__pycache__/cart.cpython-313.pyc b/routes/__pycache__/cart.cpython-313.pyc new file mode 100644 index 0000000..1445e1c Binary files /dev/null and b/routes/__pycache__/cart.cpython-313.pyc differ diff --git a/routes/__pycache__/dotori.cpython-313.pyc b/routes/__pycache__/dotori.cpython-313.pyc new file mode 100644 index 0000000..620dd9d Binary files /dev/null and b/routes/__pycache__/dotori.cpython-313.pyc differ diff --git a/routes/__pycache__/order.cpython-313.pyc b/routes/__pycache__/order.cpython-313.pyc new file mode 100644 index 0000000..763c957 Binary files /dev/null and b/routes/__pycache__/order.cpython-313.pyc differ diff --git a/routes/__pycache__/product.cpython-313.pyc b/routes/__pycache__/product.cpython-313.pyc new file mode 100644 index 0000000..ea07c03 Binary files /dev/null and b/routes/__pycache__/product.cpython-313.pyc differ diff --git a/routes/dotori.py b/routes/dotori.py new file mode 100644 index 0000000..0a71287 --- /dev/null +++ b/routes/dotori.py @@ -0,0 +1,40 @@ +from flask_restx import Namespace, Resource, fields +from services.dotori_service import DotoriService + +dotori_ns = Namespace('dotory', description='도토리 관련 API') + +user_model = dotori_ns.model('UserDotori', { + 'userId': fields.Integer, + 'dotory': fields.Integer, +}) + +@dotori_ns.route('/') +class UserDotori(Resource): + @dotori_ns.marshal_with(user_model) + def get(self, userId): + user_dotori = DotoriService.get_user_dotori(userId) + if not user_dotori: + dotori_ns.abort(404, 'User not found') + return user_dotori.to_response() + +@dotori_ns.route('') +class InitializeDotori(Resource): + @dotori_ns.expect(dotori_ns.model('Initialize', {'userId': fields.String(required=True)})) + def post(self): + data = dotori_ns.payload + user_id = data.get('userId') + return DotoriService.initialize_user_dotori(user_id) + +@dotori_ns.route('/') +class AddDotori(Resource): + @dotori_ns.expect(dotori_ns.model('AddDotori', {'num': fields.Integer(required=True)})) + def put(self, userId): + data = dotori_ns.payload + num = data.get('num') + return DotoriService.add_dotori(userId, num) + +@dotori_ns.route('/all') +class GetAllDotori(Resource): + def get(self): + users = DotoriService.get_all_users_dotori() + return users \ No newline at end of file diff --git a/routes/product.py b/routes/product.py new file mode 100644 index 0000000..d8f4a43 --- /dev/null +++ b/routes/product.py @@ -0,0 +1,37 @@ +from flask_restx import Namespace, Resource, fields +from services.dotori_service import DotoriService + +product_ns = Namespace('buy', description='상품 구매 API') + +buy_request_model = product_ns.model('BuyRequest', { + 'userId': fields.Integer(required=True), +}) + +buy_response_model = product_ns.model('BuyResponse', { + 'isSuccess': fields.Boolean, + 'userId': fields.Integer, + 'dotory': fields.Integer, +}) + +@product_ns.route('/') +class BuyProduct(Resource): + @product_ns.expect(buy_request_model) + @product_ns.response(200, 'Success', buy_response_model) + @product_ns.response(400, 'Failed') + def post(self, productId): + data = product_ns.payload + user_id = data.get('userId') + if not user_id: + product_ns.abort(400, 'userId is required') + + product_price = 100 # 가격이 얼마에요? + success = DotoriService.buy_product(user_id, product_price) + if success: + user_dotori = DotoriService.get_user_dotori(user_id) + return { + 'isSuccess': True, + 'userId': user_id, + 'dotory': user_dotori if user_dotori else 0 + } + else: + product_ns.abort(400, 'Insufficient dotory or purchase failed') \ No newline at end of file diff --git a/services/__pycache__/dotori_service.cpython-313.pyc b/services/__pycache__/dotori_service.cpython-313.pyc new file mode 100644 index 0000000..6c01416 Binary files /dev/null and b/services/__pycache__/dotori_service.cpython-313.pyc differ diff --git a/services/dotori_service.py b/services/dotori_service.py new file mode 100644 index 0000000..6660c88 --- /dev/null +++ b/services/dotori_service.py @@ -0,0 +1,49 @@ +from models.dotori import UserDotori +from flask import current_app +from db import db +class DotoriService: + @staticmethod + def get_user_dotori(user_id: str): + user_dotori = UserDotori.query.filter_by(user_id=user_id).first() + if user_dotori: + return user_dotori.dotori_count + return None + + @staticmethod + def initialize_user_dotori(user_id: str): + user_dotori = UserDotori.query.filter_by(user_id=user_id).first() + if not user_dotori: + user_dotori = UserDotori(user_id=user_id, dotori_count=1000000) + print(f"초기화 완료, {user_id}님의 도토리: {user_dotori.dotori_count}") + db.session.add(user_dotori) + db.session.commit() + return user_dotori.dotori_count + + @staticmethod + def buy_product(user_id: str, product_price: int): + user_dotori = UserDotori.query.filter_by(user_id=user_id).first() + if not user_dotori: + return False + + if user_dotori.dotori_count < product_price: + return False + print(f"구매 완료, {user_id}님의 도토리: {user_dotori.dotori_count} -> {user_dotori.dotori_count - product_price}") + user_dotori.decrement(product_price) + db.session.commit() + return True + + @staticmethod + def add_dotori(user_id: str, amount: int): + user_dotori = UserDotori.query.filter_by(user_id=user_id).first() + if not user_dotori: + user_dotori = UserDotori(user_id=user_id) + db.session.add(user_dotori) + print(f"도토리 추가, {user_id}님의 도토리: {user_dotori.dotori_count} -> {user_dotori.dotori_count + amount}") + user_dotori.increment(amount) + db.session.commit() + return user_dotori.dotori_count + + @staticmethod + def get_all_users_dotori(): + users = UserDotori.query.all() + return [user.to_dict() for user in users]