first commit
This commit is contained in:
351
api/docs/APPWRITE_SETUP.md
Normal file
351
api/docs/APPWRITE_SETUP.md
Normal file
@@ -0,0 +1,351 @@
|
||||
# Appwrite Setup Guide
|
||||
|
||||
This guide walks you through setting up Appwrite for Code of Conquest.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Appwrite Cloud account (https://cloud.appwrite.io) OR self-hosted Appwrite instance
|
||||
- Admin access to create projects and collections
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Create Project
|
||||
|
||||
1. Log in to Appwrite Console
|
||||
2. Click **"Create Project"**
|
||||
3. Project Name: `Code of Conquest`
|
||||
4. Project ID: (auto-generated, save this for `.env`)
|
||||
5. Click **"Create"**
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Get API Credentials
|
||||
|
||||
1. In your project, go to **Settings**
|
||||
2. Copy the following values:
|
||||
- **Project ID** → `.env` as `APPWRITE_PROJECT_ID`
|
||||
- **API Endpoint** → `.env` as `APPWRITE_ENDPOINT` (usually `https://cloud.appwrite.io/v1`)
|
||||
3. Go to **Settings** → **API Keys**
|
||||
4. Click **"Create API Key"**
|
||||
- Name: `Backend Server`
|
||||
- Expiration: Never (or long-term)
|
||||
- Scopes: Select ALL scopes (for development)
|
||||
5. Copy the generated API key → `.env` as `APPWRITE_API_KEY`
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Create Database
|
||||
|
||||
1. Go to **Databases** in the left sidebar
|
||||
2. Click **"Create Database"**
|
||||
3. Database ID: `main`
|
||||
4. Name: `Main Database`
|
||||
5. Click **"Create"**
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Create Collections
|
||||
|
||||
Create the following collections in the `main` database.
|
||||
|
||||
### Collection 1: characters
|
||||
|
||||
| Setting | Value |
|
||||
|---------|-------|
|
||||
| Collection ID | `characters` |
|
||||
| Collection Name | `Characters` |
|
||||
|
||||
**Attributes:**
|
||||
|
||||
| Key | Type | Size | Required | Default | Array |
|
||||
|-----|------|------|----------|---------|-------|
|
||||
| `userId` | String | 255 | Yes | - | No |
|
||||
| `characterData` | String | 100000 | Yes | - | No |
|
||||
| `created_at` | DateTime | - | Yes | - | No |
|
||||
| `updated_at` | DateTime | - | Yes | - | No |
|
||||
| `is_active` | Boolean | - | Yes | true | No |
|
||||
|
||||
**Indexes:**
|
||||
|
||||
| Key | Type | Attributes |
|
||||
|-----|------|------------|
|
||||
| `userId_index` | Key | `userId` (ASC) |
|
||||
| `active_index` | Key | `is_active` (ASC) |
|
||||
|
||||
**Permissions:**
|
||||
- Create: `users`
|
||||
- Read: `users`
|
||||
- Update: `users`
|
||||
- Delete: `users`
|
||||
|
||||
### Collection 2: game_sessions
|
||||
|
||||
| Setting | Value |
|
||||
|---------|-------|
|
||||
| Collection ID | `game_sessions` |
|
||||
| Collection Name | `Game Sessions` |
|
||||
|
||||
**Attributes:**
|
||||
|
||||
| Key | Type | Size | Required | Default | Array |
|
||||
|-----|------|------|----------|---------|-------|
|
||||
| `party_member_ids` | String | 255 | Yes | - | Yes |
|
||||
| `config` | String | 5000 | Yes | - | No |
|
||||
| `combat_encounter` | String | 50000 | No | - | No |
|
||||
| `conversation_history` | String | 500000 | Yes | - | No |
|
||||
| `game_state` | String | 50000 | Yes | - | No |
|
||||
| `turn_order` | String | 255 | Yes | - | Yes |
|
||||
| `current_turn` | Integer | - | Yes | 0 | No |
|
||||
| `turn_number` | Integer | - | Yes | 1 | No |
|
||||
| `created_at` | DateTime | - | Yes | - | No |
|
||||
| `last_activity` | DateTime | - | Yes | - | No |
|
||||
| `status` | String | 50 | Yes | active | No |
|
||||
|
||||
**Indexes:**
|
||||
|
||||
| Key | Type | Attributes |
|
||||
|-----|------|------------|
|
||||
| `status_index` | Key | `status` (ASC) |
|
||||
| `last_activity_index` | Key | `last_activity` (DESC) |
|
||||
|
||||
**Permissions:**
|
||||
- Create: `users`
|
||||
- Read: `users`
|
||||
- Update: `users`
|
||||
- Delete: `users`
|
||||
|
||||
### Collection 3: marketplace_listings
|
||||
|
||||
| Setting | Value |
|
||||
|---------|-------|
|
||||
| Collection ID | `marketplace_listings` |
|
||||
| Collection Name | `Marketplace Listings` |
|
||||
|
||||
**Attributes:**
|
||||
|
||||
| Key | Type | Size | Required | Default | Array |
|
||||
|-----|------|------|----------|---------|-------|
|
||||
| `seller_id` | String | 255 | Yes | - | No |
|
||||
| `character_id` | String | 255 | Yes | - | No |
|
||||
| `item_data` | String | 10000 | Yes | - | No |
|
||||
| `listing_type` | String | 50 | Yes | - | No |
|
||||
| `price` | Integer | - | No | - | No |
|
||||
| `starting_bid` | Integer | - | No | - | No |
|
||||
| `current_bid` | Integer | - | No | - | No |
|
||||
| `buyout_price` | Integer | - | No | - | No |
|
||||
| `bids` | String | 50000 | No | - | No |
|
||||
| `auction_end` | DateTime | - | No | - | No |
|
||||
| `status` | String | 50 | Yes | active | No |
|
||||
| `created_at` | DateTime | - | Yes | - | No |
|
||||
|
||||
**Indexes:**
|
||||
|
||||
| Key | Type | Attributes |
|
||||
|-----|------|------------|
|
||||
| `listing_type_index` | Key | `listing_type` (ASC) |
|
||||
| `status_index` | Key | `status` (ASC) |
|
||||
| `seller_index` | Key | `seller_id` (ASC) |
|
||||
| `auction_end_index` | Key | `auction_end` (ASC) |
|
||||
|
||||
**Permissions:**
|
||||
- Create: `users`
|
||||
- Read: `any` (public can browse)
|
||||
- Update: `users` (owner only, enforced in code)
|
||||
- Delete: `users` (owner only, enforced in code)
|
||||
|
||||
### Collection 4: transactions
|
||||
|
||||
| Setting | Value |
|
||||
|---------|-------|
|
||||
| Collection ID | `transactions` |
|
||||
| Collection Name | `Transactions` |
|
||||
|
||||
**Attributes:**
|
||||
|
||||
| Key | Type | Size | Required | Default | Array |
|
||||
|-----|------|------|----------|---------|-------|
|
||||
| `buyer_id` | String | 255 | Yes | - | No |
|
||||
| `seller_id` | String | 255 | Yes | - | No |
|
||||
| `listing_id` | String | 255 | No | - | No |
|
||||
| `item_data` | String | 10000 | Yes | - | No |
|
||||
| `price` | Integer | - | Yes | - | No |
|
||||
| `timestamp` | DateTime | - | Yes | - | No |
|
||||
| `transaction_type` | String | 50 | Yes | - | No |
|
||||
|
||||
**Indexes:**
|
||||
|
||||
| Key | Type | Attributes |
|
||||
|-----|------|------------|
|
||||
| `buyer_index` | Key | `buyer_id` (ASC) |
|
||||
| `seller_index` | Key | `seller_id` (ASC) |
|
||||
| `timestamp_index` | Key | `timestamp` (DESC) |
|
||||
|
||||
**Permissions:**
|
||||
- Create: System only (API key)
|
||||
- Read: `users` (buyer/seller only, enforced in code)
|
||||
- Update: None
|
||||
- Delete: None
|
||||
|
||||
---
|
||||
|
||||
## Step 5: Enable Realtime
|
||||
|
||||
1. Go to **Settings** → **Realtime**
|
||||
2. Enable **Realtime API**
|
||||
3. Add allowed origins:
|
||||
- `http://localhost:5000` (development)
|
||||
- Your production domain (when ready)
|
||||
|
||||
---
|
||||
|
||||
## Step 6: Configure Authentication
|
||||
|
||||
1. Go to **Auth** in the left sidebar
|
||||
2. Enable **Email/Password** authentication
|
||||
3. Configure password requirements:
|
||||
- Minimum length: 8
|
||||
- Require lowercase: Yes
|
||||
- Require uppercase: Yes
|
||||
- Require numbers: Yes
|
||||
- Require special characters: Optional
|
||||
|
||||
**Optional:** Enable OAuth providers if desired (Google, GitHub, etc.)
|
||||
|
||||
---
|
||||
|
||||
## Step 7: Update .env File
|
||||
|
||||
Copy `.env.example` to `.env` and fill in the values:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Update the following in `.env`:
|
||||
|
||||
```bash
|
||||
APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1
|
||||
APPWRITE_PROJECT_ID=your-project-id-here
|
||||
APPWRITE_API_KEY=your-api-key-here
|
||||
APPWRITE_DATABASE_ID=main
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 8: Test Connection
|
||||
|
||||
Create a test script to verify Appwrite connection:
|
||||
|
||||
**test_appwrite.py:**
|
||||
|
||||
```python
|
||||
from appwrite.client import Client
|
||||
from appwrite.services.databases import Databases
|
||||
from dotenv import load_dotenv
|
||||
import os
|
||||
|
||||
load_dotenv()
|
||||
|
||||
# Initialize Appwrite client
|
||||
client = Client()
|
||||
client.set_endpoint(os.getenv('APPWRITE_ENDPOINT'))
|
||||
client.set_project(os.getenv('APPWRITE_PROJECT_ID'))
|
||||
client.set_key(os.getenv('APPWRITE_API_KEY'))
|
||||
|
||||
# Test database connection
|
||||
databases = Databases(client)
|
||||
|
||||
try:
|
||||
# List collections
|
||||
result = databases.list_collections(
|
||||
database_id=os.getenv('APPWRITE_DATABASE_ID')
|
||||
)
|
||||
print(f"✓ Connected to Appwrite successfully!")
|
||||
print(f"✓ Found {result['total']} collections:")
|
||||
for collection in result['collections']:
|
||||
print(f" - {collection['name']} (ID: {collection['$id']})")
|
||||
except Exception as e:
|
||||
print(f"✗ Failed to connect to Appwrite:")
|
||||
print(f" Error: {str(e)}")
|
||||
```
|
||||
|
||||
Run:
|
||||
```bash
|
||||
source venv/bin/activate
|
||||
pip install appwrite python-dotenv
|
||||
python test_appwrite.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
### Production Permissions
|
||||
|
||||
**For production, tighten permissions:**
|
||||
|
||||
1. **characters collection:**
|
||||
- Users can only access their own characters (enforce in code)
|
||||
- Add server-side checks for `userId` match
|
||||
|
||||
2. **game_sessions collection:**
|
||||
- Party members can read (enforce in code)
|
||||
- Active player can write (enforce in code)
|
||||
|
||||
3. **marketplace_listings collection:**
|
||||
- Anyone can read (browsing)
|
||||
- Only owner can update/delete (enforce in code)
|
||||
|
||||
4. **transactions collection:**
|
||||
- Create via API key only
|
||||
- Users can read only their own transactions (enforce in code)
|
||||
|
||||
### API Key Security
|
||||
|
||||
- **Never commit** `.env` file to git
|
||||
- Use different API keys for dev/staging/production
|
||||
- Rotate API keys periodically
|
||||
- Use minimal scopes in production (not "all")
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
**Issue:** "Project not found"
|
||||
- Solution: Verify `APPWRITE_PROJECT_ID` matches the project ID in Appwrite Console
|
||||
|
||||
**Issue:** "Invalid API key"
|
||||
- Solution: Regenerate API key and update `.env`
|
||||
|
||||
**Issue:** "Collection not found"
|
||||
- Solution: Verify collection IDs match exactly (case-sensitive)
|
||||
|
||||
**Issue:** "Permission denied"
|
||||
- Solution: Check collection permissions in Appwrite Console
|
||||
|
||||
**Issue:** "Realtime not working"
|
||||
- Solution: Verify Realtime is enabled and origins are configured
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
After completing Appwrite setup:
|
||||
|
||||
1. ✅ Install dependencies: `pip install -r requirements.txt`
|
||||
2. ✅ Test connection with `test_appwrite.py`
|
||||
3. ✅ Create Appwrite service wrapper (`app/services/appwrite_service.py`)
|
||||
4. Start building API endpoints (Phase 2)
|
||||
|
||||
---
|
||||
|
||||
## Resources
|
||||
|
||||
- **Appwrite Documentation:** https://appwrite.io/docs
|
||||
- **Appwrite Python SDK:** https://github.com/appwrite/sdk-for-python
|
||||
- **Appwrite Console:** https://cloud.appwrite.io
|
||||
- **Appwrite Discord:** https://appwrite.io/discord
|
||||
Reference in New Issue
Block a user