A basic HackerNews-like clone where posts can be submitted with url links and then up and down voted.
- CRUD (Query + Mutation Operations)
- Cursor Based Pagination
- Authorization / RLS
- Next.js - React Framework
- TypeScript - TypeScript is a strongly typed programming language that builds on JavaScript, giving you better tooling at any scale.
- graphql-code-generator - Generate code from your GraphQL schema and operations with a simple CLI
- gql-tag-operations-preset - This code gen preset generates typings for your inline gql function usages, without having to manually specify import statements for the documents
- urql - A highly customizable and versatile GraphQL client
- Gravatar - Default avatar profile images from Gravatar
- Supabase - Create a backend in less than 2 minutes. Start your project with a Postgres Database, Authentication, instant APIs, Realtime subscriptions and Storage.
- pg_graphql - A native PostgreSQL extension adding GraphQL support. The extension keeps schema generation, query parsing, and resolvers all neatly contained on your database server requiring no external services.
- Postgres Triggers and Postgres Functions - When votes are in, use triggers to invoke a Postgres function that calculates a post score to rank the feed
- Postgres Enumerated Types - Enums help defined the direction of a vote: UP or DOWN.
- Registration
- Get a ranked feed of posts
- Create Post
- Delete Post
- Create Comment
- Delete Comment
- Upvote/Downvote Post
- View Profile (Account)
- View Profile (Public)
- Pagination (Posts, Comments)
cp app/.env.example app/.env
- Fill in your url and anon key from the Supabase Dashboard: https://app.supabase.io/project/_/settings/api
yarn
yarn codegen
yarn workspace app dev
Provide the following settings to deploy a production build to Vercel:
- BUILD COMMAND:
yarn codegen && yarn workspace app build
- OUTPUT DIRECTORY:
./app/.next
- INSTALL COMMAND:
yarn
- DEVELOPMENT COMMAND:
yarn codegen && yarn workspace app dev --port $PORT
- Fetch latest GraphQL Schema
yarn codegen:fetch
- Generate Types and Watch for Changes
yarn codegen:watch
- Run server
yarn workspace app dev
Note: You need to call select graphql.rebuild_schema()
manually to synchronize the GraphQL schema with the SQL schema after altering the SQL schema.
brew install dbmate
- Setup
.env
withDATABASE_URL
- Dump Schema
cd data
dbmate dump
Note: If
pgdump
fails due to row locks, a workaround is to grant thepostgres
role superuser permissions withALTER USER postgres WITH SUPERUSER
. After dumping the schema, you should reset the permissions usingALTER USER postgres WITH NOSUPERUSER
. You can run these statements in the Superbase Dashboard SQL Editors.
-
Profile belongs to auth.users
-
Post
-
Comment belongs to Post and Profile
-
Vote belongs to Post (can have a direction of UP/DOWN)
-
direction enum is "UP" or "DOWN"
- Post
url
is unique - Vote is unique per Profile, Post (ie, you cannot vote more than once -- up or down)
See: ./data/db/schema.sql
Note: The schema includes the entire Supabase schema with auth, storage, functions, etc.
A data file for all Supabase Blog posts from the RSS feed can be found in ./data/seed/blog_posts.csv
and can be loaded. Another file for comments
is available as well.
Note: Assumes a known profileId
currently.
See: ./graphql/schema/schema.graphql
See: ./graphql/queries/
Use: https://mvrfvzcivgabojxddwtk.supabase.co/graphql/v1
Note: Needs headers
Content-Type: application/json
apiKey: <supabase_anon_key>
GraphiQL is an in-browser IDE for writing, validating, and testing GraphQL queries.
Visit http://localhost:3000/api/graphiql
for the Yoga GraphiQL Playground where you can experiment with queries and mutations.
Note: Needs headers
Content-Type: application/json
apiKey: <supabase_anon_key>
Note: In order for the RLS policies authenticate you. you've have to pass an authorization header:
authorization: Bearker <access_token>
query {
rankedFeed: postCollection(
orderBy: [
{ voteRank: AscNullsFirst }
{ score: DescNullsFirst }
{ createdAt: DescNullsFirst }
]
) {
edges {
post: node {
id
title
url
upVoteTotal
downVoteTotal
voteTotal
voteDelta
score
voteRank
comments: commentCollection {
edges {
node {
id
message
profile {
id
username
avatarUrl
}
}
}
commentCount: totalCount
}
}
}
}
}
You can query all policies via: select * from pg_policies
.
See: Row Level Security Matrix (RLS)
dbmate
can createschema_migrations
tables in schemas. To make sure they are not included in your GraphQL Schema:
revoke select on table public.schema_migrations from anon, authenticated;
comment on schema public is e'@graphql({"inflect_names": true})';