first commit
This commit is contained in:
311
INVENTORY_MARKET_SUMMARY.md
Normal file
311
INVENTORY_MARKET_SUMMARY.md
Normal file
@@ -0,0 +1,311 @@
|
||||
# Inventory, Market, and Sell System - Summary
|
||||
|
||||
## What Was Implemented
|
||||
|
||||
### 1. Session Pills - Invalidated Status ✅
|
||||
|
||||
**Feature**: Inactive/revoked sessions now show an "INVALIDATED" pill next to the session ID.
|
||||
|
||||
**Location**: ProfilePage.vue - Active Sessions section
|
||||
|
||||
**Display**:
|
||||
- Active sessions: Show colored session ID pill only (e.g., `0ED72A`)
|
||||
- Inactive sessions: Show session ID pill + gray "INVALIDATED" pill
|
||||
|
||||
**Code**:
|
||||
```vue
|
||||
<span v-if="!session.isActive" class="px-2 py-0.5 rounded text-[10px] font-medium bg-gray-600 text-gray-300">
|
||||
INVALIDATED
|
||||
</span>
|
||||
```
|
||||
|
||||
### 2. Market Page - Database Integration ✅
|
||||
|
||||
**Feature**: Market now displays items from the MongoDB database.
|
||||
|
||||
**Backend Route**: `/api/market/items` (already existed)
|
||||
|
||||
**Filters Available**:
|
||||
- Game (CS2, Rust)
|
||||
- Category (rifles, pistols, knives, gloves, etc.)
|
||||
- Rarity
|
||||
- Wear (for CS2)
|
||||
- Price range
|
||||
- Search by name
|
||||
- Sort options
|
||||
|
||||
**Item Status**: Only shows items with `status: 'active'`
|
||||
|
||||
**How It Works**:
|
||||
1. Frontend calls `/api/market/items` with filters
|
||||
2. Backend queries `Item` collection
|
||||
3. Returns paginated results with seller info
|
||||
4. Items are displayed in grid layout
|
||||
|
||||
### 3. Sell Page - Steam Inventory Integration ✅
|
||||
|
||||
**Feature**: Users can fetch their Steam inventory and sell items to the site at 100% calculated price.
|
||||
|
||||
**New Backend Routes**:
|
||||
|
||||
#### `GET /api/inventory/steam`
|
||||
- Fetches user's Steam inventory from Steam API
|
||||
- Query params: `game` (cs2 or rust)
|
||||
- Filters for marketable and tradable items only
|
||||
- Returns item details with images from Steam CDN
|
||||
|
||||
**Steam App IDs**:
|
||||
- CS2: 730
|
||||
- Rust: 252490
|
||||
|
||||
#### `POST /api/inventory/price`
|
||||
- Calculates prices for selected items
|
||||
- Uses placeholder pricing logic (replace with real pricing API)
|
||||
- Returns items with `estimatedPrice` field
|
||||
|
||||
**Pricing Logic** (placeholder - use real API in production):
|
||||
- Base prices for popular items (Dragon Lore, Howl, Fire Serpent, etc.)
|
||||
- Wear multipliers (FN: 1.0, MW: 0.85, FT: 0.70, WW: 0.55, BS: 0.40)
|
||||
- StatTrak™ items get 1.5x multiplier
|
||||
- Knives, gloves, and high-tier skins have higher base prices
|
||||
|
||||
#### `POST /api/inventory/sell`
|
||||
- Sells selected items to the site
|
||||
- Adds items to marketplace at 100% of calculated price
|
||||
- Credits user's balance immediately
|
||||
- Creates `Item` documents with `status: 'active'`
|
||||
|
||||
**Sale Flow**:
|
||||
1. User fetches Steam inventory
|
||||
2. System calculates prices
|
||||
3. User selects items to sell
|
||||
4. Items are added to marketplace
|
||||
5. Balance is credited instantly
|
||||
6. Items appear in market for other users to purchase
|
||||
|
||||
### 4. File Structure
|
||||
|
||||
**New Files**:
|
||||
- `routes/inventory.js` - Inventory and sell routes
|
||||
|
||||
**Modified Files**:
|
||||
- `index.js` - Registered inventory routes
|
||||
- `frontend/src/views/ProfilePage.vue` - Added INVALIDATED pill
|
||||
|
||||
**Existing Files Used**:
|
||||
- `routes/market.js` - Market routes (already functional)
|
||||
- `models/Item.js` - Item schema
|
||||
- `frontend/src/views/MarketPage.vue` - Market display
|
||||
- `frontend/src/views/SellPage.vue` - Sell interface (needs frontend update)
|
||||
|
||||
## API Endpoints Summary
|
||||
|
||||
### Inventory Routes
|
||||
- `GET /api/inventory/steam?game=cs2` - Fetch Steam inventory
|
||||
- `POST /api/inventory/price` - Calculate item prices
|
||||
- `POST /api/inventory/sell` - Sell items to site
|
||||
|
||||
### Market Routes (Existing)
|
||||
- `GET /api/market/items` - Browse marketplace
|
||||
- `GET /api/market/featured` - Featured items
|
||||
- `GET /api/market/recent-sales` - Recent sales
|
||||
- `GET /api/market/items/:id` - Single item details
|
||||
- `POST /api/market/purchase/:id` - Purchase item
|
||||
- `GET /api/market/stats` - Marketplace statistics
|
||||
|
||||
## Data Flow
|
||||
|
||||
### Selling Items
|
||||
```
|
||||
User Steam Inventory
|
||||
↓
|
||||
GET /api/inventory/steam (fetch items)
|
||||
↓
|
||||
POST /api/inventory/price (calculate prices)
|
||||
↓
|
||||
User selects items
|
||||
↓
|
||||
POST /api/inventory/sell
|
||||
↓
|
||||
├── Create Item documents (status: 'active')
|
||||
├── Credit user balance
|
||||
└── Broadcast to WebSocket
|
||||
↓
|
||||
Items appear in market
|
||||
```
|
||||
|
||||
### Marketplace
|
||||
```
|
||||
Database (Item collection)
|
||||
↓
|
||||
GET /api/market/items
|
||||
↓
|
||||
Filter by status: 'active'
|
||||
↓
|
||||
Apply user filters (game, category, price, etc.)
|
||||
↓
|
||||
Return paginated results
|
||||
↓
|
||||
Display in MarketPage
|
||||
```
|
||||
|
||||
## Item Schema
|
||||
|
||||
```javascript
|
||||
{
|
||||
name: String,
|
||||
description: String,
|
||||
image: String (URL),
|
||||
game: 'cs2' | 'rust',
|
||||
category: 'rifles' | 'pistols' | 'knives' | 'gloves' | etc.,
|
||||
rarity: 'common' | 'uncommon' | 'rare' | 'mythical' | 'legendary' | etc.,
|
||||
wear: 'fn' | 'mw' | 'ft' | 'ww' | 'bs' | null,
|
||||
statTrak: Boolean,
|
||||
souvenir: Boolean,
|
||||
price: Number,
|
||||
seller: ObjectId (User),
|
||||
buyer: ObjectId (User) | null,
|
||||
status: 'active' | 'sold' | 'removed',
|
||||
featured: Boolean,
|
||||
listedAt: Date,
|
||||
soldAt: Date | null,
|
||||
views: Number
|
||||
}
|
||||
```
|
||||
|
||||
## Frontend Updates Needed
|
||||
|
||||
### SellPage.vue (TODO)
|
||||
You need to update the SellPage.vue to:
|
||||
|
||||
1. **Add inventory loading**:
|
||||
```javascript
|
||||
const loadInventory = async (game) => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const response = await axios.get('/api/inventory/steam', {
|
||||
params: { game },
|
||||
withCredentials: true
|
||||
});
|
||||
items.value = response.data.items;
|
||||
} catch (error) {
|
||||
toast.error(error.response?.data?.message || 'Failed to load inventory');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
2. **Add pricing**:
|
||||
```javascript
|
||||
const getPrices = async (selectedItems) => {
|
||||
try {
|
||||
const response = await axios.post('/api/inventory/price', {
|
||||
items: selectedItems
|
||||
}, { withCredentials: true });
|
||||
return response.data.items;
|
||||
} catch (error) {
|
||||
toast.error('Failed to calculate prices');
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
3. **Add sell function**:
|
||||
```javascript
|
||||
const sellItems = async (itemsToSell) => {
|
||||
try {
|
||||
const response = await axios.post('/api/inventory/sell', {
|
||||
items: itemsToSell
|
||||
}, { withCredentials: true });
|
||||
|
||||
toast.success(response.data.message);
|
||||
await authStore.fetchUser(); // Refresh balance
|
||||
loadInventory(currentGame.value); // Reload inventory
|
||||
} catch (error) {
|
||||
toast.error('Failed to sell items');
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Important Notes
|
||||
|
||||
### Steam API Considerations
|
||||
1. **Private Inventories**: Users must set inventory to public in Steam settings
|
||||
2. **Rate Limits**: Steam API has rate limits (implement caching/throttling)
|
||||
3. **Timeout**: Set 15s timeout for Steam API requests
|
||||
4. **Error Handling**: Handle 403 (private), 404 (not found), timeout errors
|
||||
|
||||
### Pricing
|
||||
The current pricing logic is a **placeholder**. In production:
|
||||
- Use a real pricing API (e.g., SteamApis, CSGOBackpack, etc.)
|
||||
- Implement price caching to reduce API calls
|
||||
- Update prices periodically
|
||||
- Consider market trends and demand
|
||||
|
||||
### Site Buy Price
|
||||
Currently set to **100% of calculated price**. You may want to:
|
||||
- Adjust to 70-90% to allow profit margin
|
||||
- Add dynamic pricing based on supply/demand
|
||||
- Offer instant-sell vs. list-for-sale options
|
||||
|
||||
### Transaction Recording
|
||||
Consider creating Transaction records when:
|
||||
- User sells items to site (credit balance)
|
||||
- Link transactions to sessionId for tracking
|
||||
|
||||
### Security
|
||||
- ✅ Authenticate all inventory/sell routes
|
||||
- ✅ Verify item ownership before sale
|
||||
- ⚠️ TODO: Implement trade offer system with Steam bot
|
||||
- ⚠️ TODO: Validate items are still in user's inventory before completing sale
|
||||
|
||||
## Testing
|
||||
|
||||
### Test Market
|
||||
1. Start backend: `npm run dev`
|
||||
2. Navigate to `/market`
|
||||
3. Should see items from database
|
||||
4. Apply filters, search, pagination
|
||||
|
||||
### Test Sell (Backend)
|
||||
Use a tool like Postman or curl:
|
||||
|
||||
```bash
|
||||
# Fetch inventory
|
||||
curl -X GET "http://localhost:3000/api/inventory/steam?game=cs2" \
|
||||
-H "Cookie: accessToken=YOUR_TOKEN"
|
||||
|
||||
# Price items
|
||||
curl -X POST "http://localhost:3000/api/inventory/price" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Cookie: accessToken=YOUR_TOKEN" \
|
||||
-d '{"items": [{"name": "AK-47 | Redline", "wear": "ft"}]}'
|
||||
|
||||
# Sell items
|
||||
curl -X POST "http://localhost:3000/api/inventory/sell" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Cookie: accessToken=YOUR_TOKEN" \
|
||||
-d '{"items": [...]}'
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Update SellPage.vue frontend** with the API calls
|
||||
2. **Implement real pricing API** (CSGOBackpack, SteamApis, etc.)
|
||||
3. **Add price caching** to reduce external API calls
|
||||
4. **Implement Steam bot** for trade offers
|
||||
5. **Add item validation** before completing sales
|
||||
6. **Create transaction records** for all sell operations
|
||||
7. **Add loading states** and better error handling in frontend
|
||||
8. **Test with real Steam inventories**
|
||||
|
||||
## Summary
|
||||
|
||||
✅ **Session pills** - Show INVALIDATED status for inactive sessions
|
||||
✅ **Market** - Already displays items from database with full filtering
|
||||
✅ **Backend routes** - Complete inventory/sell system implemented
|
||||
⏳ **Frontend** - SellPage.vue needs API integration (backend ready)
|
||||
⚠️ **Pricing** - Using placeholder logic (implement real API)
|
||||
⚠️ **Trade system** - Steam bot integration needed for trade offers
|
||||
|
||||
The backend infrastructure is **complete and ready**. The market works out of the box. You just need to update the SellPage.vue frontend to call the inventory APIs!
|
||||
Reference in New Issue
Block a user