Moving to github

This commit is contained in:
2026-03-28 19:24:29 -04:00
commit 036fa7ab33
302 changed files with 17838 additions and 0 deletions

View File

@@ -0,0 +1,377 @@
<div class="max-w-5xl mx-auto">
<div class="bg-white rounded-lg shadow-lg p-8 mb-6">
<h1 class="text-4xl font-bold text-gray-900 mb-4">TurboVault API Documentation</h1>
<p class="text-lg text-gray-600 mb-6">
RESTful API for accessing and managing your video game collection programmatically.
</p>
<!-- Quick Start -->
<div class="bg-indigo-50 border-l-4 border-indigo-500 p-4 mb-6">
<h2 class="text-xl font-bold text-indigo-900 mb-2">Quick Start</h2>
<ol class="list-decimal list-inside space-y-2 text-indigo-800">
<li><%= link_to "Generate an API token", settings_api_tokens_path, class: "underline hover:text-indigo-600" %> in your settings</li>
<li>Include the token in the <code class="bg-indigo-100 px-2 py-1 rounded">Authorization</code> header</li>
<li>Make requests to <code class="bg-indigo-100 px-2 py-1 rounded">https://yourdomain.com/api/v1/...</code></li>
</ol>
</div>
</div>
<!-- Table of Contents -->
<div class="bg-white rounded-lg shadow p-6 mb-6">
<h2 class="text-2xl font-bold mb-4">Table of Contents</h2>
<ul class="space-y-2">
<li><a href="#authentication" class="text-indigo-600 hover:text-indigo-800">Authentication</a></li>
<li><a href="#games" class="text-indigo-600 hover:text-indigo-800">Games</a></li>
<li><a href="#collections" class="text-indigo-600 hover:text-indigo-800">Collections</a></li>
<li><a href="#platforms" class="text-indigo-600 hover:text-indigo-800">Platforms</a></li>
<li><a href="#genres" class="text-indigo-600 hover:text-indigo-800">Genres</a></li>
<li><a href="#errors" class="text-indigo-600 hover:text-indigo-800">Error Handling</a></li>
<li><a href="#rate-limits" class="text-indigo-600 hover:text-indigo-800">Rate Limits</a></li>
</ul>
</div>
<!-- Authentication -->
<div id="authentication" class="bg-white rounded-lg shadow p-6 mb-6">
<h2 class="text-2xl font-bold mb-4">Authentication</h2>
<p class="text-gray-700 mb-4">All API requests require authentication using a bearer token.</p>
<div class="bg-gray-900 text-gray-100 p-4 rounded mb-4 overflow-x-auto">
<pre><code>Authorization: Bearer YOUR_API_TOKEN_HERE</code></pre>
</div>
<p class="text-sm text-gray-600 mb-4">
<%= link_to "Generate a token", settings_api_tokens_path, class: "text-indigo-600 hover:text-indigo-800" %> in your settings page.
</p>
<div class="bg-yellow-50 border-l-4 border-yellow-500 p-4">
<p class="text-sm text-yellow-800">
<strong>Security:</strong> Keep your API tokens secure. Do not share them or commit them to version control.
</p>
</div>
</div>
<!-- Games Endpoints -->
<div id="games" class="bg-white rounded-lg shadow p-6 mb-6">
<h2 class="text-2xl font-bold mb-4">Games</h2>
<!-- List Games -->
<div class="mb-8 pb-8 border-b">
<h3 class="text-xl font-semibold mb-2">List Games</h3>
<div class="flex items-center gap-2 mb-4">
<span class="px-3 py-1 bg-green-100 text-green-800 font-mono text-sm rounded">GET</span>
<code class="text-gray-700">/api/v1/games</code>
</div>
<p class="text-gray-700 mb-4">Returns a paginated list of your games.</p>
<h4 class="font-semibold mb-2">Query Parameters:</h4>
<table class="w-full text-sm mb-4">
<tr class="border-b">
<td class="py-2 font-mono">page</td>
<td class="py-2 text-gray-600">Page number (default: 1)</td>
</tr>
<tr class="border-b">
<td class="py-2 font-mono">per_page</td>
<td class="py-2 text-gray-600">Items per page (default: 50, max: 100)</td>
</tr>
<tr class="border-b">
<td class="py-2 font-mono">format</td>
<td class="py-2 text-gray-600">Filter by format: <code>physical</code> or <code>digital</code></td>
</tr>
<tr class="border-b">
<td class="py-2 font-mono">platform_id</td>
<td class="py-2 text-gray-600">Filter by platform ID</td>
</tr>
<tr class="border-b">
<td class="py-2 font-mono">genre_id</td>
<td class="py-2 text-gray-600">Filter by genre ID</td>
</tr>
</table>
<h4 class="font-semibold mb-2">Example Request:</h4>
<div class="bg-gray-900 text-gray-100 p-4 rounded mb-4 overflow-x-auto">
<pre><code>curl -X GET "https://yourdomain.com/api/v1/games?page=1&per_page=10" \
-H "Authorization: Bearer YOUR_TOKEN"</code></pre>
</div>
<h4 class="font-semibold mb-2">Example Response:</h4>
<div class="bg-gray-900 text-gray-100 p-4 rounded overflow-x-auto">
<pre><code>{
"games": [
{
"id": 1,
"title": "The Legend of Zelda: Ocarina of Time",
"platform": "Nintendo 64",
"format": "physical",
"date_added": "2024-01-15",
"completion_status": "completed",
"user_rating": 5,
"igdb_id": 1234,
"condition": "very_good",
"price_paid": "45.99",
"location": "Bedroom Shelf A",
"genres": ["Action", "Adventure"],
"collections": ["Favorites", "N64 Collection"]
}
],
"pagination": {
"current_page": 1,
"per_page": 10,
"total_pages": 3,
"total_count": 25
}
}</code></pre>
</div>
</div>
<!-- Get Single Game -->
<div class="mb-8 pb-8 border-b">
<h3 class="text-xl font-semibold mb-2">Get a Game</h3>
<div class="flex items-center gap-2 mb-4">
<span class="px-3 py-1 bg-green-100 text-green-800 font-mono text-sm rounded">GET</span>
<code class="text-gray-700">/api/v1/games/:id</code>
</div>
<p class="text-gray-700 mb-4">Returns details for a specific game.</p>
<h4 class="font-semibold mb-2">Example Request:</h4>
<div class="bg-gray-900 text-gray-100 p-4 rounded overflow-x-auto">
<pre><code>curl -X GET "https://yourdomain.com/api/v1/games/1" \
-H "Authorization: Bearer YOUR_TOKEN"</code></pre>
</div>
</div>
<!-- Create Game -->
<div class="mb-8 pb-8 border-b">
<h3 class="text-xl font-semibold mb-2">Create a Game</h3>
<div class="flex items-center gap-2 mb-4">
<span class="px-3 py-1 bg-blue-100 text-blue-800 font-mono text-sm rounded">POST</span>
<code class="text-gray-700">/api/v1/games</code>
</div>
<p class="text-gray-700 mb-4">Add a new game to your collection.</p>
<h4 class="font-semibold mb-2">Request Body:</h4>
<div class="bg-gray-900 text-gray-100 p-4 rounded mb-4 overflow-x-auto">
<pre><code>{
"game": {
"title": "Super Mario 64",
"platform_id": 4,
"format": "physical",
"date_added": "2024-03-28",
"completion_status": "backlog",
"user_rating": null,
"condition": "good",
"price_paid": "35.00",
"location": "Living Room Shelf",
"genre_ids": [1, 3],
"collection_ids": [2]
}
}</code></pre>
</div>
</div>
<!-- Update Game -->
<div class="mb-8 pb-8 border-b">
<h3 class="text-xl font-semibold mb-2">Update a Game</h3>
<div class="flex items-center gap-2 mb-4">
<span class="px-3 py-1 bg-yellow-100 text-yellow-800 font-mono text-sm rounded">PUT/PATCH</span>
<code class="text-gray-700">/api/v1/games/:id</code>
</div>
<p class="text-gray-700 mb-4">Update an existing game's information.</p>
</div>
<!-- Delete Game -->
<div class="mb-8">
<h3 class="text-xl font-semibold mb-2">Delete a Game</h3>
<div class="flex items-center gap-2 mb-4">
<span class="px-3 py-1 bg-red-100 text-red-800 font-mono text-sm rounded">DELETE</span>
<code class="text-gray-700">/api/v1/games/:id</code>
</div>
<p class="text-gray-700 mb-4">Permanently delete a game from your collection.</p>
</div>
</div>
<!-- Collections Endpoints -->
<div id="collections" class="bg-white rounded-lg shadow p-6 mb-6">
<h2 class="text-2xl font-bold mb-4">Collections</h2>
<div class="mb-6">
<h3 class="text-xl font-semibold mb-2">List Collections</h3>
<div class="flex items-center gap-2 mb-4">
<span class="px-3 py-1 bg-green-100 text-green-800 font-mono text-sm rounded">GET</span>
<code class="text-gray-700">/api/v1/collections</code>
</div>
</div>
<div class="mb-6">
<h3 class="text-xl font-semibold mb-2">Get a Collection</h3>
<div class="flex items-center gap-2 mb-4">
<span class="px-3 py-1 bg-green-100 text-green-800 font-mono text-sm rounded">GET</span>
<code class="text-gray-700">/api/v1/collections/:id</code>
</div>
<p class="text-gray-700 text-sm">Includes all games in the collection.</p>
</div>
<div class="mb-6">
<h3 class="text-xl font-semibold mb-2">Create a Collection</h3>
<div class="flex items-center gap-2 mb-4">
<span class="px-3 py-1 bg-blue-100 text-blue-800 font-mono text-sm rounded">POST</span>
<code class="text-gray-700">/api/v1/collections</code>
</div>
</div>
<div class="mb-6">
<h3 class="text-xl font-semibold mb-2">Update a Collection</h3>
<div class="flex items-center gap-2 mb-4">
<span class="px-3 py-1 bg-yellow-100 text-yellow-800 font-mono text-sm rounded">PUT/PATCH</span>
<code class="text-gray-700">/api/v1/collections/:id</code>
</div>
</div>
<div>
<h3 class="text-xl font-semibold mb-2">Delete a Collection</h3>
<div class="flex items-center gap-2 mb-4">
<span class="px-3 py-1 bg-red-100 text-red-800 font-mono text-sm rounded">DELETE</span>
<code class="text-gray-700">/api/v1/collections/:id</code>
</div>
<p class="text-gray-700 text-sm">Games in the collection will not be deleted.</p>
</div>
</div>
<!-- Platforms -->
<div id="platforms" class="bg-white rounded-lg shadow p-6 mb-6">
<h2 class="text-2xl font-bold mb-4">Platforms</h2>
<div class="mb-6">
<h3 class="text-xl font-semibold mb-2">List Platforms</h3>
<div class="flex items-center gap-2 mb-4">
<span class="px-3 py-1 bg-green-100 text-green-800 font-mono text-sm rounded">GET</span>
<code class="text-gray-700">/api/v1/platforms</code>
</div>
<p class="text-gray-700 text-sm">Returns all available gaming platforms.</p>
</div>
<div>
<h3 class="text-xl font-semibold mb-2">Get a Platform</h3>
<div class="flex items-center gap-2 mb-4">
<span class="px-3 py-1 bg-green-100 text-green-800 font-mono text-sm rounded">GET</span>
<code class="text-gray-700">/api/v1/platforms/:id</code>
</div>
</div>
</div>
<!-- Genres -->
<div id="genres" class="bg-white rounded-lg shadow p-6 mb-6">
<h2 class="text-2xl font-bold mb-4">Genres</h2>
<div class="mb-6">
<h3 class="text-xl font-semibold mb-2">List Genres</h3>
<div class="flex items-center gap-2 mb-4">
<span class="px-3 py-1 bg-green-100 text-green-800 font-mono text-sm rounded">GET</span>
<code class="text-gray-700">/api/v1/genres</code>
</div>
<p class="text-gray-700 text-sm">Returns all available game genres.</p>
</div>
<div>
<h3 class="text-xl font-semibold mb-2">Get a Genre</h3>
<div class="flex items-center gap-2 mb-4">
<span class="px-3 py-1 bg-green-100 text-green-800 font-mono text-sm rounded">GET</span>
<code class="text-gray-700">/api/v1/genres/:id</code>
</div>
</div>
</div>
<!-- Error Handling -->
<div id="errors" class="bg-white rounded-lg shadow p-6 mb-6">
<h2 class="text-2xl font-bold mb-4">Error Handling</h2>
<p class="text-gray-700 mb-4">The API uses standard HTTP response codes:</p>
<table class="w-full text-sm mb-4">
<thead class="bg-gray-50">
<tr>
<th class="py-2 px-4 text-left">Code</th>
<th class="py-2 px-4 text-left">Meaning</th>
</tr>
</thead>
<tbody>
<tr class="border-b">
<td class="py-2 px-4 font-mono">200</td>
<td class="py-2 px-4 text-gray-600">Success</td>
</tr>
<tr class="border-b">
<td class="py-2 px-4 font-mono">201</td>
<td class="py-2 px-4 text-gray-600">Created</td>
</tr>
<tr class="border-b">
<td class="py-2 px-4 font-mono">400</td>
<td class="py-2 px-4 text-gray-600">Bad Request - Invalid parameters</td>
</tr>
<tr class="border-b">
<td class="py-2 px-4 font-mono">401</td>
<td class="py-2 px-4 text-gray-600">Unauthorized - Invalid or missing token</td>
</tr>
<tr class="border-b">
<td class="py-2 px-4 font-mono">404</td>
<td class="py-2 px-4 text-gray-600">Not Found</td>
</tr>
<tr class="border-b">
<td class="py-2 px-4 font-mono">422</td>
<td class="py-2 px-4 text-gray-600">Unprocessable Entity - Validation errors</td>
</tr>
<tr class="border-b">
<td class="py-2 px-4 font-mono">429</td>
<td class="py-2 px-4 text-gray-600">Too Many Requests - Rate limit exceeded</td>
</tr>
<tr>
<td class="py-2 px-4 font-mono">500</td>
<td class="py-2 px-4 text-gray-600">Internal Server Error</td>
</tr>
</tbody>
</table>
<h4 class="font-semibold mb-2">Error Response Format:</h4>
<div class="bg-gray-900 text-gray-100 p-4 rounded overflow-x-auto">
<pre><code>{
"error": "Validation failed",
"details": {
"title": ["can't be blank"],
"platform_id": ["must exist"]
}
}</code></pre>
</div>
</div>
<!-- Rate Limits -->
<div id="rate-limits" class="bg-white rounded-lg shadow p-6 mb-6">
<h2 class="text-2xl font-bold mb-4">Rate Limits</h2>
<p class="text-gray-700 mb-4">
API requests are currently not rate-limited, but this may change in the future.
Please be respectful and avoid excessive requests.
</p>
<div class="bg-blue-50 border-l-4 border-blue-500 p-4">
<p class="text-sm text-blue-800">
<strong>Best Practice:</strong> Cache responses when possible and implement exponential backoff for failed requests.
</p>
</div>
</div>
<!-- Support -->
<div class="bg-white rounded-lg shadow p-6">
<h2 class="text-2xl font-bold mb-4">Need Help?</h2>
<p class="text-gray-700 mb-4">
If you have questions or encounter issues with the API:
</p>
<ul class="list-disc list-inside space-y-2 text-gray-700">
<li>Check the <%= link_to "API tokens page", settings_api_tokens_path, class: "text-indigo-600 hover:text-indigo-800" %> for troubleshooting</li>
<li>Review this documentation for endpoint details</li>
<li>Contact support if you need assistance</li>
</ul>
</div>
</div>

View File

@@ -0,0 +1,26 @@
<div class="max-w-4xl mx-auto text-center py-16">
<h1 class="text-5xl font-bold text-gray-900 mb-6">Welcome to TurboVault</h1>
<p class="text-xl text-gray-600 mb-8">Track and manage your video game collection with ease</p>
<div class="space-x-4">
<%= link_to "Get Started", signup_path, class: "px-8 py-3 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 text-lg font-semibold" %>
<%= link_to "Login", login_path, class: "px-8 py-3 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 text-lg font-semibold" %>
</div>
<div class="mt-16 grid grid-cols-1 md:grid-cols-3 gap-8">
<div class="bg-white p-6 rounded-lg shadow">
<h3 class="text-xl font-bold mb-2">Track Your Collection</h3>
<p class="text-gray-600">Manage both physical and digital games across all platforms</p>
</div>
<div class="bg-white p-6 rounded-lg shadow">
<h3 class="text-xl font-bold mb-2">Organize with Collections</h3>
<p class="text-gray-600">Create custom collections and subcollections for your games</p>
</div>
<div class="bg-white p-6 rounded-lg shadow">
<h3 class="text-xl font-bold mb-2">View Statistics</h3>
<p class="text-gray-600">See insights about your collection with detailed stats</p>
</div>
</div>
</div>