docs: add migration system documentation and generated initial migrations

Added `README.md` to document the database migration system, including generation and usage instructions. Updated `generate-migrations.ts` to fix directory structure and streamline commands. Included initial migration files for schema setup using DrizzleORM.
This commit is contained in:
Mathis H (Avnyr) 2025-05-15 18:08:30 +02:00
parent 7b6da2767e
commit 9515c32016
6 changed files with 1013 additions and 11 deletions

View File

@ -0,0 +1,54 @@
# Database Migrations
This directory contains the migration system for the database. The migrations are generated using DrizzleORM and are stored in the `sql` subdirectory.
## Directory Structure
- `sql/` - Contains the generated SQL migration files
- `generate-migrations.ts` - Script to generate migration files
- `migrate.ts` - Script to run migrations
- `README.md` - This file
## How to Use
### Generating Migrations
To generate migrations based on changes to the schema, run:
```bash
npm run db:generate:ts
```
This will generate SQL migration files in the `sql` directory.
### Running Migrations
To run all pending migrations, run:
```bash
npm run db:migrate
```
### Generating and Running Migrations in One Step
To generate and run migrations in one step, run:
```bash
npm run db:update
```
## Integration with NestJS
The migrations are automatically run when the application starts. This is configured in the `DatabaseService` class in `src/database/database.service.ts`.
## Migration Files
Migration files are SQL files that contain the SQL statements to create, alter, or drop database objects. They are named with a timestamp and a description, e.g. `0000_lively_tiger_shark.sql`.
## Configuration
The migration system is configured in `drizzle.config.ts` at the root of the project. This file specifies:
- The schema file to use for generating migrations
- The output directory for migration files
- The database dialect and credentials

View File

@ -14,13 +14,13 @@ const main = async () => {
console.log('Generating migrations...');
// Ensure migrations directory exists
const migrationsDir = path.join(__dirname);
const migrationsDir = path.join(__dirname, 'sql');
if (!fs.existsSync(migrationsDir)) {
fs.mkdirSync(migrationsDir, { recursive: true });
}
// Run drizzle-kit generate command
const command = 'npx drizzle-kit generate:pg';
const command = 'npx drizzle-kit generate';
exec(command, (error, stdout, stderr) => {
if (error) {

View File

@ -57,7 +57,7 @@ export const runMigrations = async (options?: { migrationsFolder?: string }) =>
}
// Determine migrations folder path
const migrationsFolder = options?.migrationsFolder || path.join(__dirname);
const migrationsFolder = options?.migrationsFolder || path.join(__dirname, 'sql');
console.log(`Using migrations folder: ${migrationsFolder}`);
// Run migrations

View File

@ -0,0 +1,173 @@
CREATE SCHEMA "groupmaker";
--> statement-breakpoint
DO $$ BEGIN
CREATE TYPE "public"."gender" AS ENUM('MALE', 'FEMALE', 'NON_BINARY');
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
CREATE TYPE "public"."oralEaseLevel" AS ENUM('SHY', 'RESERVED', 'COMFORTABLE');
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
CREATE TYPE "public"."tagType" AS ENUM('PROJECT', 'PERSON');
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "users" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"name" varchar(100) NOT NULL,
"avatar" text,
"githubId" varchar(50) NOT NULL,
"gdprTimestamp" timestamp with time zone,
"createdAt" timestamp with time zone DEFAULT now() NOT NULL,
"updatedAt" timestamp with time zone DEFAULT now() NOT NULL,
"metadata" jsonb DEFAULT '{}'::jsonb,
CONSTRAINT "users_githubId_unique" UNIQUE("githubId")
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "projects" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"name" varchar(100) NOT NULL,
"description" text,
"ownerId" uuid NOT NULL,
"settings" jsonb DEFAULT '{}'::jsonb,
"createdAt" timestamp with time zone DEFAULT now() NOT NULL,
"updatedAt" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "persons" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"firstName" varchar(50) NOT NULL,
"lastName" varchar(50) NOT NULL,
"gender" "gender" NOT NULL,
"technicalLevel" smallint NOT NULL,
"hasTechnicalTraining" boolean DEFAULT false NOT NULL,
"frenchSpeakingLevel" smallint NOT NULL,
"oralEaseLevel" "oralEaseLevel" NOT NULL,
"age" smallint,
"projectId" uuid NOT NULL,
"attributes" jsonb DEFAULT '{}'::jsonb,
"createdAt" timestamp with time zone DEFAULT now() NOT NULL,
"updatedAt" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "groups" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"name" varchar(100) NOT NULL,
"projectId" uuid NOT NULL,
"metadata" jsonb DEFAULT '{}'::jsonb,
"createdAt" timestamp with time zone DEFAULT now() NOT NULL,
"updatedAt" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "tags" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"name" varchar(50) NOT NULL,
"color" varchar(7) NOT NULL,
"type" "tagType" NOT NULL,
"createdAt" timestamp with time zone DEFAULT now() NOT NULL,
"updatedAt" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "person_to_group" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"personId" uuid NOT NULL,
"groupId" uuid NOT NULL,
"createdAt" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "person_to_tag" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"personId" uuid NOT NULL,
"tagId" uuid NOT NULL,
"createdAt" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "project_to_tag" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"projectId" uuid NOT NULL,
"tagId" uuid NOT NULL,
"createdAt" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "projects" ADD CONSTRAINT "projects_ownerId_users_id_fk" FOREIGN KEY ("ownerId") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "persons" ADD CONSTRAINT "persons_projectId_projects_id_fk" FOREIGN KEY ("projectId") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "groups" ADD CONSTRAINT "groups_projectId_projects_id_fk" FOREIGN KEY ("projectId") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "person_to_group" ADD CONSTRAINT "person_to_group_personId_persons_id_fk" FOREIGN KEY ("personId") REFERENCES "public"."persons"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "person_to_group" ADD CONSTRAINT "person_to_group_groupId_groups_id_fk" FOREIGN KEY ("groupId") REFERENCES "public"."groups"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "person_to_tag" ADD CONSTRAINT "person_to_tag_personId_persons_id_fk" FOREIGN KEY ("personId") REFERENCES "public"."persons"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "person_to_tag" ADD CONSTRAINT "person_to_tag_tagId_tags_id_fk" FOREIGN KEY ("tagId") REFERENCES "public"."tags"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "project_to_tag" ADD CONSTRAINT "project_to_tag_projectId_projects_id_fk" FOREIGN KEY ("projectId") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "project_to_tag" ADD CONSTRAINT "project_to_tag_tagId_tags_id_fk" FOREIGN KEY ("tagId") REFERENCES "public"."tags"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "githubId_idx" ON "users" ("githubId");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "createdAt_idx" ON "users" ("createdAt");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "project_name_idx" ON "projects" ("name");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "project_ownerId_idx" ON "projects" ("ownerId");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "project_createdAt_idx" ON "projects" ("createdAt");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "person_firstName_idx" ON "persons" ("firstName");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "person_lastName_idx" ON "persons" ("lastName");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "person_projectId_idx" ON "persons" ("projectId");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "person_name_composite_idx" ON "persons" ("firstName","lastName");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "group_name_idx" ON "groups" ("name");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "group_projectId_idx" ON "groups" ("projectId");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "tag_name_idx" ON "tags" ("name");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "tag_type_idx" ON "tags" ("type");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "ptg_personId_idx" ON "person_to_group" ("personId");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "ptg_groupId_idx" ON "person_to_group" ("groupId");--> statement-breakpoint
CREATE UNIQUE INDEX IF NOT EXISTS "ptg_person_group_unique_idx" ON "person_to_group" ("personId","groupId");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "ptt_personId_idx" ON "person_to_tag" ("personId");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "ptt_tagId_idx" ON "person_to_tag" ("tagId");--> statement-breakpoint
CREATE UNIQUE INDEX IF NOT EXISTS "ptt_person_tag_unique_idx" ON "person_to_tag" ("personId","tagId");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "pjt_projectId_idx" ON "project_to_tag" ("projectId");--> statement-breakpoint
CREATE INDEX IF NOT EXISTS "pjt_tagId_idx" ON "project_to_tag" ("tagId");--> statement-breakpoint
CREATE UNIQUE INDEX IF NOT EXISTS "pjt_project_tag_unique_idx" ON "project_to_tag" ("projectId","tagId");

View File

@ -0,0 +1,762 @@
{
"id": "ebffb361-7a99-4ad4-a51f-e48d304b0260",
"prevId": "00000000-0000-0000-0000-000000000000",
"version": "6",
"dialect": "postgresql",
"tables": {
"public.users": {
"name": "users",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"name": {
"name": "name",
"type": "varchar(100)",
"primaryKey": false,
"notNull": true
},
"avatar": {
"name": "avatar",
"type": "text",
"primaryKey": false,
"notNull": false
},
"githubId": {
"name": "githubId",
"type": "varchar(50)",
"primaryKey": false,
"notNull": true
},
"gdprTimestamp": {
"name": "gdprTimestamp",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"metadata": {
"name": "metadata",
"type": "jsonb",
"primaryKey": false,
"notNull": false,
"default": "'{}'::jsonb"
}
},
"indexes": {
"githubId_idx": {
"name": "githubId_idx",
"columns": [
"githubId"
],
"isUnique": false
},
"createdAt_idx": {
"name": "createdAt_idx",
"columns": [
"createdAt"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"users_githubId_unique": {
"name": "users_githubId_unique",
"nullsNotDistinct": false,
"columns": [
"githubId"
]
}
}
},
"public.projects": {
"name": "projects",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"name": {
"name": "name",
"type": "varchar(100)",
"primaryKey": false,
"notNull": true
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": false
},
"ownerId": {
"name": "ownerId",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"settings": {
"name": "settings",
"type": "jsonb",
"primaryKey": false,
"notNull": false,
"default": "'{}'::jsonb"
},
"createdAt": {
"name": "createdAt",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"project_name_idx": {
"name": "project_name_idx",
"columns": [
"name"
],
"isUnique": false
},
"project_ownerId_idx": {
"name": "project_ownerId_idx",
"columns": [
"ownerId"
],
"isUnique": false
},
"project_createdAt_idx": {
"name": "project_createdAt_idx",
"columns": [
"createdAt"
],
"isUnique": false
}
},
"foreignKeys": {
"projects_ownerId_users_id_fk": {
"name": "projects_ownerId_users_id_fk",
"tableFrom": "projects",
"tableTo": "users",
"columnsFrom": [
"ownerId"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"public.persons": {
"name": "persons",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"firstName": {
"name": "firstName",
"type": "varchar(50)",
"primaryKey": false,
"notNull": true
},
"lastName": {
"name": "lastName",
"type": "varchar(50)",
"primaryKey": false,
"notNull": true
},
"gender": {
"name": "gender",
"type": "gender",
"typeSchema": "public",
"primaryKey": false,
"notNull": true
},
"technicalLevel": {
"name": "technicalLevel",
"type": "smallint",
"primaryKey": false,
"notNull": true
},
"hasTechnicalTraining": {
"name": "hasTechnicalTraining",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"frenchSpeakingLevel": {
"name": "frenchSpeakingLevel",
"type": "smallint",
"primaryKey": false,
"notNull": true
},
"oralEaseLevel": {
"name": "oralEaseLevel",
"type": "oralEaseLevel",
"typeSchema": "public",
"primaryKey": false,
"notNull": true
},
"age": {
"name": "age",
"type": "smallint",
"primaryKey": false,
"notNull": false
},
"projectId": {
"name": "projectId",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"attributes": {
"name": "attributes",
"type": "jsonb",
"primaryKey": false,
"notNull": false,
"default": "'{}'::jsonb"
},
"createdAt": {
"name": "createdAt",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"person_firstName_idx": {
"name": "person_firstName_idx",
"columns": [
"firstName"
],
"isUnique": false
},
"person_lastName_idx": {
"name": "person_lastName_idx",
"columns": [
"lastName"
],
"isUnique": false
},
"person_projectId_idx": {
"name": "person_projectId_idx",
"columns": [
"projectId"
],
"isUnique": false
},
"person_name_composite_idx": {
"name": "person_name_composite_idx",
"columns": [
"firstName",
"lastName"
],
"isUnique": false
}
},
"foreignKeys": {
"persons_projectId_projects_id_fk": {
"name": "persons_projectId_projects_id_fk",
"tableFrom": "persons",
"tableTo": "projects",
"columnsFrom": [
"projectId"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"public.groups": {
"name": "groups",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"name": {
"name": "name",
"type": "varchar(100)",
"primaryKey": false,
"notNull": true
},
"projectId": {
"name": "projectId",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"metadata": {
"name": "metadata",
"type": "jsonb",
"primaryKey": false,
"notNull": false,
"default": "'{}'::jsonb"
},
"createdAt": {
"name": "createdAt",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"group_name_idx": {
"name": "group_name_idx",
"columns": [
"name"
],
"isUnique": false
},
"group_projectId_idx": {
"name": "group_projectId_idx",
"columns": [
"projectId"
],
"isUnique": false
}
},
"foreignKeys": {
"groups_projectId_projects_id_fk": {
"name": "groups_projectId_projects_id_fk",
"tableFrom": "groups",
"tableTo": "projects",
"columnsFrom": [
"projectId"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"public.tags": {
"name": "tags",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"name": {
"name": "name",
"type": "varchar(50)",
"primaryKey": false,
"notNull": true
},
"color": {
"name": "color",
"type": "varchar(7)",
"primaryKey": false,
"notNull": true
},
"type": {
"name": "type",
"type": "tagType",
"typeSchema": "public",
"primaryKey": false,
"notNull": true
},
"createdAt": {
"name": "createdAt",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"tag_name_idx": {
"name": "tag_name_idx",
"columns": [
"name"
],
"isUnique": false
},
"tag_type_idx": {
"name": "tag_type_idx",
"columns": [
"type"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"public.person_to_group": {
"name": "person_to_group",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"personId": {
"name": "personId",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"groupId": {
"name": "groupId",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"createdAt": {
"name": "createdAt",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"ptg_personId_idx": {
"name": "ptg_personId_idx",
"columns": [
"personId"
],
"isUnique": false
},
"ptg_groupId_idx": {
"name": "ptg_groupId_idx",
"columns": [
"groupId"
],
"isUnique": false
},
"ptg_person_group_unique_idx": {
"name": "ptg_person_group_unique_idx",
"columns": [
"personId",
"groupId"
],
"isUnique": true
}
},
"foreignKeys": {
"person_to_group_personId_persons_id_fk": {
"name": "person_to_group_personId_persons_id_fk",
"tableFrom": "person_to_group",
"tableTo": "persons",
"columnsFrom": [
"personId"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"person_to_group_groupId_groups_id_fk": {
"name": "person_to_group_groupId_groups_id_fk",
"tableFrom": "person_to_group",
"tableTo": "groups",
"columnsFrom": [
"groupId"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"public.person_to_tag": {
"name": "person_to_tag",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"personId": {
"name": "personId",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"tagId": {
"name": "tagId",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"createdAt": {
"name": "createdAt",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"ptt_personId_idx": {
"name": "ptt_personId_idx",
"columns": [
"personId"
],
"isUnique": false
},
"ptt_tagId_idx": {
"name": "ptt_tagId_idx",
"columns": [
"tagId"
],
"isUnique": false
},
"ptt_person_tag_unique_idx": {
"name": "ptt_person_tag_unique_idx",
"columns": [
"personId",
"tagId"
],
"isUnique": true
}
},
"foreignKeys": {
"person_to_tag_personId_persons_id_fk": {
"name": "person_to_tag_personId_persons_id_fk",
"tableFrom": "person_to_tag",
"tableTo": "persons",
"columnsFrom": [
"personId"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"person_to_tag_tagId_tags_id_fk": {
"name": "person_to_tag_tagId_tags_id_fk",
"tableFrom": "person_to_tag",
"tableTo": "tags",
"columnsFrom": [
"tagId"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"public.project_to_tag": {
"name": "project_to_tag",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "uuid",
"primaryKey": true,
"notNull": true,
"default": "gen_random_uuid()"
},
"projectId": {
"name": "projectId",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"tagId": {
"name": "tagId",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"createdAt": {
"name": "createdAt",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"pjt_projectId_idx": {
"name": "pjt_projectId_idx",
"columns": [
"projectId"
],
"isUnique": false
},
"pjt_tagId_idx": {
"name": "pjt_tagId_idx",
"columns": [
"tagId"
],
"isUnique": false
},
"pjt_project_tag_unique_idx": {
"name": "pjt_project_tag_unique_idx",
"columns": [
"projectId",
"tagId"
],
"isUnique": true
}
},
"foreignKeys": {
"project_to_tag_projectId_projects_id_fk": {
"name": "project_to_tag_projectId_projects_id_fk",
"tableFrom": "project_to_tag",
"tableTo": "projects",
"columnsFrom": [
"projectId"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"project_to_tag_tagId_tags_id_fk": {
"name": "project_to_tag_tagId_tags_id_fk",
"tableFrom": "project_to_tag",
"tableTo": "tags",
"columnsFrom": [
"tagId"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
}
},
"enums": {
"public.gender": {
"name": "gender",
"schema": "public",
"values": [
"MALE",
"FEMALE",
"NON_BINARY"
]
},
"public.oralEaseLevel": {
"name": "oralEaseLevel",
"schema": "public",
"values": [
"SHY",
"RESERVED",
"COMFORTABLE"
]
},
"public.tagType": {
"name": "tagType",
"schema": "public",
"values": [
"PROJECT",
"PERSON"
]
}
},
"schemas": {
"groupmaker": "groupmaker"
},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}

View File

@ -0,0 +1,13 @@
{
"version": "6",
"dialect": "postgresql",
"entries": [
{
"idx": 0,
"version": "6",
"when": 1747322785586,
"tag": "0000_lively_tiger_shark",
"breakpoints": true
}
]
}