mirror of
https://github.com/jcreek/LivingDexTracker.git
synced 2026-07-13 02:53:45 +00:00
Merge pull request #70 from jcreek/69-cant-create-account-clicking-sign-up-does-nothing
69 Set up Docker and Supabase workflow with seeding migrations
This commit is contained in:
+3
-1
@@ -1,2 +1,4 @@
|
|||||||
PUBLIC_SUPABASE_URL="your-supabase-project-url"
|
PUBLIC_SUPABASE_URL="your-supabase-project-url"
|
||||||
PUBLIC_SUPABASE_ANON_KEY="your-supabase-anon-key"
|
PUBLIC_SUPABASE_ANON_KEY="your-supabase-anon-key"
|
||||||
|
SUPABASE_SERVICE_ROLE_KEY="your-supabase-service-role-key"
|
||||||
|
PUBLIC_USE_LOCAL_POKEMON_SPRITE_FOLDER="false"
|
||||||
@@ -4,18 +4,20 @@ A web app to track completion of a living Pokédex.
|
|||||||
|
|
||||||
## Developing
|
## Developing
|
||||||
|
|
||||||
Cloned the repository you can install the dependencies with `npm install`, and start a development server:
|
1. Clone the repository
|
||||||
|
2. Install the dependencies with `npm install`
|
||||||
|
3. Ensure that Docker is running
|
||||||
|
4. An example `.env` file is provided in the repository. You will need to copy `.env.example` to `.env` and fill in the values with your own credentials. For local development with Supabase running in Docker, you can use the following values:
|
||||||
|
|
||||||
```bash
|
- The `PUBLIC_SUPABASE_URL` will be `"http://127.0.0.1:54321"`
|
||||||
npm run dev
|
- The `PUBLIC_SUPABASE_ANON_KEY` will be the 'Publishable' authentication key displayed when you run Supabase in the terminal
|
||||||
|
- The `SUPABASE_SERVICE_ROLE_KEY` will be the 'Secret' authentication key displayed when you run Supabase in the terminal
|
||||||
|
|
||||||
# or start the server and open the app in a new browser tab
|
5. Start local Supabase and a development server with `npm run dev:supabase`
|
||||||
npm run dev -- --open
|
6. The Pokédex data is automatically seeded via database migrations when Supabase starts
|
||||||
```
|
7. Create an account using the sign-up form and access the email it sends in [MailPit](http://127.0.0.1:54324/) to verify your email address.
|
||||||
|
N.B. All local emails are captured by MailPit when running Supabase in Docker.
|
||||||
An example `.env` file is provided in the repository. You will need to copy `.env.example` to `.env` and fill in the values with your own credentials.
|
8. You can now use [the app](http://localhost:5173/).
|
||||||
|
|
||||||
Once you have done this, you can seed the Pokédex data using the /api/seed endpoint. You will need to comment out the `return;` at the beginning of the `GET` function in `/src/routes/api/seed.ts` to do this. Make sure you remember to uncomment it afterwards.
|
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
|
|||||||
Generated
+1337
-771
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -38,7 +38,7 @@
|
|||||||
"@sveltejs/adapter-netlify": "^4.1.0",
|
"@sveltejs/adapter-netlify": "^4.1.0",
|
||||||
"@sveltejs/adapter-node": "^2.0.0",
|
"@sveltejs/adapter-node": "^2.0.0",
|
||||||
"@sveltejs/adapter-static": "^3.0.0",
|
"@sveltejs/adapter-static": "^3.0.0",
|
||||||
"@sveltejs/kit": "^2.0.6",
|
"@sveltejs/kit": "^2.5.3",
|
||||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
||||||
"@types/cookie": "^0.6.0",
|
"@types/cookie": "^0.6.0",
|
||||||
"@types/eslint": "^8.56.0",
|
"@types/eslint": "^8.56.0",
|
||||||
@@ -54,6 +54,7 @@
|
|||||||
"postcss": "^8.4.38",
|
"postcss": "^8.4.38",
|
||||||
"prettier": "^3.1.1",
|
"prettier": "^3.1.1",
|
||||||
"prettier-plugin-svelte": "^3.1.2",
|
"prettier-plugin-svelte": "^3.1.2",
|
||||||
|
"supabase": "^2.70.5",
|
||||||
"svelte": "^4.2.8",
|
"svelte": "^4.2.8",
|
||||||
"svelte-check": "^3.6.2",
|
"svelte-check": "^3.6.2",
|
||||||
"tailwindcss": "^3.4.3",
|
"tailwindcss": "^3.4.3",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { json } from '@sveltejs/kit';
|
import { json } from '@sveltejs/kit';
|
||||||
import { createClient } from '@supabase/supabase-js';
|
import { createClient } from '@supabase/supabase-js';
|
||||||
import { PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY } from '$env/static/public';
|
import { PUBLIC_SUPABASE_URL } from '$env/static/public';
|
||||||
|
import { SUPABASE_SERVICE_ROLE_KEY } from '$env/static/private';
|
||||||
import dex from '$lib/helpers/pokedex.json';
|
import dex from '$lib/helpers/pokedex.json';
|
||||||
import RegionGameMappingJson from '$lib/helpers/region-game-mapping.json';
|
import RegionGameMappingJson from '$lib/helpers/region-game-mapping.json';
|
||||||
|
|
||||||
@@ -10,20 +11,21 @@ export const GET = async () => {
|
|||||||
return json({ message: 'Seeding not allowed in production' }, { status: 403 });
|
return json({ message: 'Seeding not allowed in production' }, { status: 403 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const supabase = createClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY);
|
// Use service role key to bypass RLS for seeding operations
|
||||||
|
const supabase = createClient(PUBLIC_SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Seed Pokédex entries
|
// Seed Pokédex entries
|
||||||
const { data: existingEntries, error: countError } = await supabase
|
const { count: entriesCount, error: countError } = await supabase
|
||||||
.from('pokedex_entries')
|
.from('pokedex_entries')
|
||||||
.select('id', { count: 'exact', head: true });
|
.select('*', { count: 'exact', head: true });
|
||||||
|
|
||||||
if (countError) {
|
if (countError) {
|
||||||
throw new Error(`Failed to check existing entries: ${countError.message}`);
|
throw new Error(`Failed to check existing entries: ${countError.message}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only seed if table is empty
|
// Only seed if table is empty
|
||||||
if (!existingEntries || existingEntries.length === 0) {
|
if (!entriesCount || entriesCount === 0) {
|
||||||
console.log('Seeding Pokédex entries...');
|
console.log('Seeding Pokédex entries...');
|
||||||
|
|
||||||
// Transform data to match database schema
|
// Transform data to match database schema
|
||||||
@@ -57,11 +59,11 @@ export const GET = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Seed region-game mappings (check if table exists first)
|
// Seed region-game mappings (check if table exists first)
|
||||||
const { data: existingMappings, error: mappingCountError } = await supabase
|
const { count: mappingsCount, error: mappingCountError } = await supabase
|
||||||
.from('region_game_mappings')
|
.from('region_game_mappings')
|
||||||
.select('id', { count: 'exact', head: true });
|
.select('*', { count: 'exact', head: true });
|
||||||
|
|
||||||
if (!mappingCountError && (!existingMappings || existingMappings.length === 0)) {
|
if (!mappingCountError && (!mappingsCount || mappingsCount === 0)) {
|
||||||
console.log('Seeding region-game mappings...');
|
console.log('Seeding region-game mappings...');
|
||||||
|
|
||||||
const { error: mappingInsertError } = await supabase
|
const { error: mappingInsertError } = await supabase
|
||||||
@@ -80,9 +82,8 @@ export const GET = async () => {
|
|||||||
return json({
|
return json({
|
||||||
message: 'Seeding completed successfully',
|
message: 'Seeding completed successfully',
|
||||||
seeded: {
|
seeded: {
|
||||||
pokemonEntries: !existingEntries || existingEntries.length === 0,
|
pokemonEntries: !entriesCount || entriesCount === 0,
|
||||||
regionGameMappings:
|
regionGameMappings: !mappingCountError && (!mappingsCount || mappingsCount === 0)
|
||||||
!mappingCountError && (!existingMappings || existingMappings.length === 0)
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -117,9 +117,9 @@ file_size_limit = "50MiB"
|
|||||||
enabled = true
|
enabled = true
|
||||||
# The base URL of your website. Used as an allow-list for redirects and for constructing URLs used
|
# The base URL of your website. Used as an allow-list for redirects and for constructing URLs used
|
||||||
# in emails.
|
# in emails.
|
||||||
site_url = "http://127.0.0.1:3000"
|
site_url = "http://localhost:5173"
|
||||||
# A list of *exact* URLs that auth providers are permitted to redirect to post authentication.
|
# A list of *exact* URLs that auth providers are permitted to redirect to post authentication.
|
||||||
additional_redirect_urls = ["http://127.0.0.1:3000"]
|
additional_redirect_urls = ["http://localhost:5173"]
|
||||||
# How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week).
|
# How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week).
|
||||||
jwt_expiry = 3600
|
jwt_expiry = 3600
|
||||||
# If disabled, the refresh token will never expire.
|
# If disabled, the refresh token will never expire.
|
||||||
|
|||||||
Reference in New Issue
Block a user