Skip to content

Commit f6f15ac

Browse files
authored
Merge pull request #1 from listee-dev/feature-project-api-init
Add Drizzle migrations and expose category/task endpoints
2 parents 1d0f964 + c9c6c94 commit f6f15ac

21 files changed

Lines changed: 2119 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- "**"
10+
11+
permissions:
12+
contents: write
13+
pull-requests: write
14+
id-token: write
15+
16+
jobs:
17+
lint:
18+
uses: listee-dev/listee-ci/.github/workflows/lint.yml@main
19+
20+
typecheck:
21+
uses: listee-dev/listee-ci/.github/workflows/typecheck.yml@main

.gitignore

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.*
7+
.yarn/*
8+
!.yarn/patches
9+
!.yarn/plugins
10+
!.yarn/releases
11+
!.yarn/versions
12+
13+
# testing
14+
/coverage
15+
16+
# next.js
17+
/.next/
18+
/out/
19+
20+
# production
21+
/build
22+
23+
# misc
24+
.DS_Store
25+
*.pem
26+
27+
# debug
28+
npm-debug.log*
29+
yarn-debug.log*
30+
yarn-error.log*
31+
.pnpm-debug.log*
32+
33+
# env files (can opt-in for committing if needed)
34+
.env*
35+
36+
# vercel
37+
.vercel
38+
39+
# typescript
40+
*.tsbuildinfo
41+
next-env.d.ts

biome.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/2.2.0/schema.json",
3+
"vcs": {
4+
"enabled": true,
5+
"clientKind": "git",
6+
"useIgnoreFile": true
7+
},
8+
"files": {
9+
"ignoreUnknown": true,
10+
"includes": ["**", "!node_modules", "!.next", "!dist", "!build", "!drizzle"]
11+
},
12+
"formatter": {
13+
"enabled": true,
14+
"indentStyle": "space",
15+
"indentWidth": 2
16+
},
17+
"linter": {
18+
"enabled": true,
19+
"rules": {
20+
"recommended": true
21+
},
22+
"domains": {
23+
"next": "recommended",
24+
"react": "recommended"
25+
}
26+
},
27+
"assist": {
28+
"actions": {
29+
"source": {
30+
"organizeImports": "on"
31+
}
32+
}
33+
}
34+
}

bun.lock

Lines changed: 295 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

drizzle.config.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { schemaPath } from "@listee/db";
2+
import { loadEnvConfig } from "@next/env";
3+
import { defineConfig } from "drizzle-kit";
4+
5+
loadEnvConfig(process.cwd());
6+
7+
const databaseUrl = process.env.POSTGRES_URL;
8+
9+
if (databaseUrl === undefined || databaseUrl.length === 0) {
10+
throw new Error("POSTGRES_URL is not set.");
11+
}
12+
13+
export default defineConfig({
14+
dialect: "postgresql",
15+
schema: schemaPath,
16+
out: "./drizzle",
17+
dbCredentials: {
18+
url: databaseUrl,
19+
},
20+
});
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
CREATE TABLE "categories" (
2+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3+
"name" text NOT NULL,
4+
"kind" text NOT NULL,
5+
"created_by" uuid NOT NULL,
6+
"updated_by" uuid NOT NULL,
7+
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
8+
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
9+
);
10+
--> statement-breakpoint
11+
ALTER TABLE "categories" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
12+
CREATE TABLE "profiles" (
13+
"id" uuid PRIMARY KEY NOT NULL,
14+
"email" text NOT NULL,
15+
"name" text,
16+
"default_category_id" uuid,
17+
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
18+
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
19+
CONSTRAINT "profiles_email_unique" UNIQUE("email")
20+
);
21+
--> statement-breakpoint
22+
ALTER TABLE "profiles" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
23+
CREATE TABLE "tasks" (
24+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
25+
"name" text NOT NULL,
26+
"description" text,
27+
"is_checked" boolean DEFAULT false NOT NULL,
28+
"category_id" uuid NOT NULL,
29+
"created_by" uuid NOT NULL,
30+
"updated_by" uuid NOT NULL,
31+
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
32+
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
33+
);
34+
--> statement-breakpoint
35+
ALTER TABLE "tasks" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
36+
ALTER TABLE "categories" ADD CONSTRAINT "categories_created_by_profiles_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."profiles"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
37+
ALTER TABLE "categories" ADD CONSTRAINT "categories_updated_by_profiles_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."profiles"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
38+
ALTER TABLE "tasks" ADD CONSTRAINT "tasks_category_id_categories_id_fk" FOREIGN KEY ("category_id") REFERENCES "public"."categories"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
39+
ALTER TABLE "tasks" ADD CONSTRAINT "tasks_created_by_profiles_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."profiles"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
40+
ALTER TABLE "tasks" ADD CONSTRAINT "tasks_updated_by_profiles_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."profiles"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
41+
CREATE UNIQUE INDEX "categories_system_name_idx" ON "categories" USING btree ("created_by","name") WHERE "categories"."kind" = 'system';--> statement-breakpoint
42+
CREATE POLICY "Users can view their categories" ON "categories" AS PERMISSIVE FOR SELECT TO "authenticated" USING ("categories"."created_by" = (select auth.uid()));--> statement-breakpoint
43+
CREATE POLICY "Users can insert categories" ON "categories" AS PERMISSIVE FOR INSERT TO "authenticated" WITH CHECK ("categories"."created_by" = (select auth.uid()));--> statement-breakpoint
44+
CREATE POLICY "Users can update their categories" ON "categories" AS PERMISSIVE FOR UPDATE TO "authenticated" USING ("categories"."created_by" = (select auth.uid())) WITH CHECK ("categories"."created_by" = (select auth.uid()));--> statement-breakpoint
45+
CREATE POLICY "Users can delete their categories" ON "categories" AS PERMISSIVE FOR DELETE TO "authenticated" USING ("categories"."created_by" = (select auth.uid()));--> statement-breakpoint
46+
CREATE POLICY "Users can view their profile" ON "profiles" AS PERMISSIVE FOR SELECT TO "authenticated" USING ("profiles"."id" = (select auth.uid()));--> statement-breakpoint
47+
CREATE POLICY "Users can insert their profile" ON "profiles" AS PERMISSIVE FOR INSERT TO "authenticated" WITH CHECK ("profiles"."id" = (select auth.uid()));--> statement-breakpoint
48+
CREATE POLICY "Users can update their profile" ON "profiles" AS PERMISSIVE FOR UPDATE TO "authenticated" USING ("profiles"."id" = (select auth.uid())) WITH CHECK ("profiles"."id" = (select auth.uid()));--> statement-breakpoint
49+
CREATE POLICY "Users can view their tasks" ON "tasks" AS PERMISSIVE FOR SELECT TO "authenticated" USING (
50+
"tasks"."created_by" = (select auth.uid())
51+
OR EXISTS (
52+
SELECT 1
53+
FROM "categories"
54+
WHERE "categories"."id" = "tasks"."category_id"
55+
AND "categories"."created_by" = (select auth.uid())
56+
)
57+
);--> statement-breakpoint
58+
CREATE POLICY "Users can insert tasks in their categories" ON "tasks" AS PERMISSIVE FOR INSERT TO "authenticated" WITH CHECK (
59+
"tasks"."created_by" = (select auth.uid())
60+
OR EXISTS (
61+
SELECT 1
62+
FROM "categories"
63+
WHERE "categories"."id" = "tasks"."category_id"
64+
AND "categories"."created_by" = (select auth.uid())
65+
)
66+
);--> statement-breakpoint
67+
CREATE POLICY "Users can update their tasks" ON "tasks" AS PERMISSIVE FOR UPDATE TO "authenticated" USING (
68+
"tasks"."created_by" = (select auth.uid())
69+
OR EXISTS (
70+
SELECT 1
71+
FROM "categories"
72+
WHERE "categories"."id" = "tasks"."category_id"
73+
AND "categories"."created_by" = (select auth.uid())
74+
)
75+
) WITH CHECK (
76+
"tasks"."created_by" = (select auth.uid())
77+
OR EXISTS (
78+
SELECT 1
79+
FROM "categories"
80+
WHERE "categories"."id" = "tasks"."category_id"
81+
AND "categories"."created_by" = (select auth.uid())
82+
)
83+
);--> statement-breakpoint
84+
CREATE POLICY "Users can delete their tasks" ON "tasks" AS PERMISSIVE FOR DELETE TO "authenticated" USING (
85+
"tasks"."created_by" = (select auth.uid())
86+
OR EXISTS (
87+
SELECT 1
88+
FROM "categories"
89+
WHERE "categories"."id" = "tasks"."category_id"
90+
AND "categories"."created_by" = (select auth.uid())
91+
)
92+
);

drizzle/0001_lying_firebrand.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CREATE INDEX "idx_categories_created_by" ON "categories" USING btree ("created_by");--> statement-breakpoint
2+
CREATE INDEX "idx_categories_updated_by" ON "categories" USING btree ("updated_by");--> statement-breakpoint
3+
CREATE INDEX "idx_profiles_default_category_id" ON "profiles" USING btree ("default_category_id");--> statement-breakpoint
4+
CREATE INDEX "idx_tasks_category_id" ON "tasks" USING btree ("category_id");--> statement-breakpoint
5+
CREATE INDEX "idx_tasks_created_by" ON "tasks" USING btree ("created_by");--> statement-breakpoint
6+
CREATE INDEX "idx_tasks_updated_by" ON "tasks" USING btree ("updated_by");

drizzle/0002_gigantic_starbolt.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE "profiles" ADD CONSTRAINT "profiles_default_category_id_categories_id_fk" FOREIGN KEY ("default_category_id") REFERENCES "public"."categories"("id") ON DELETE restrict ON UPDATE no action;

0 commit comments

Comments
 (0)