1
0

Integrate ai.card Rust API with ai.gpt MCP and implement daily limit system

### Major Changes:
- **Rust Migration**: Move api-rs to root directory, rename binary to 'aicard'
- **MCP Integration**: Add card tools to ai.gpt MCP server (get_user_cards, draw_card, get_draw_status)
- **Daily Limit System**: Implement 2-day interval card drawing limits in API and iOS
- **iOS Enhancements**: Add DrawStatusView, backup functionality, and limit integration

### Technical Details:
- ai.gpt MCP now has 20 tools including 3 card-related tools
- ServiceClient enhanced with missing card API methods
- iOS app includes daily limit UI and atproto OAuth backup features
- Database migration for last_draw_date field
- Complete feature parity between web and iOS implementations

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-06-08 10:35:43 +09:00
parent 2e55e6ce09
commit 9f9208e160
14 changed files with 384 additions and 12 deletions

View File

@ -1,6 +1,7 @@
"""User repository"""
from typing import Optional
from sqlalchemy import select
from datetime import datetime, timedelta
from sqlalchemy import select, update
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
@ -35,4 +36,62 @@ class UserRepository(BaseRepository[User]):
.options(selectinload(User.cards))
.where(User.id == user_id)
)
return result.scalar_one_or_none()
return result.scalar_one_or_none()
async def can_draw_card(self, did: str, draw_limit_days: int = 2) -> bool:
"""
Check if user can draw a card based on daily limit
Args:
did: User's DID
draw_limit_days: Number of days between allowed draws (default: 2 days)
Returns:
True if user can draw, False if still in cooldown period
"""
user = await self.get_by_did(did)
if not user:
# New user can always draw
return True
if not user.last_draw_date:
# User has never drawn before
return True
# Check if enough time has passed since last draw
time_since_last_draw = datetime.utcnow() - user.last_draw_date
return time_since_last_draw >= timedelta(days=draw_limit_days)
async def get_next_draw_time(self, did: str, draw_limit_days: int = 2) -> Optional[datetime]:
"""
Get the next time the user can draw a card
Args:
did: User's DID
draw_limit_days: Number of days between allowed draws
Returns:
Next draw time if user is in cooldown, None if user can draw now
"""
user = await self.get_by_did(did)
if not user or not user.last_draw_date:
return None
next_draw_time = user.last_draw_date + timedelta(days=draw_limit_days)
if datetime.utcnow() >= next_draw_time:
return None
return next_draw_time
async def update_last_draw_date(self, user_id: int) -> None:
"""
Update user's last draw date to current time
Args:
user_id: User's database ID
"""
await self.session.execute(
update(User)
.where(User.id == user_id)
.values(last_draw_date=datetime.utcnow())
)