Browse Source

feat(db): add multitenant profile, posts, timeline, and rss tables

Made-with: Cursor
tags/邮箱功能前置
npmrun 5 days ago
parent
commit
e418d00553
  1. 7
      packages/drizzle-pkg/database/sqlite/schema/auth.ts
  2. 46
      packages/drizzle-pkg/database/sqlite/schema/content.ts
  3. 50
      packages/drizzle-pkg/database/sqlite/schema/rss.ts
  4. 1
      packages/drizzle-pkg/lib/schema/content.ts
  5. 1
      packages/drizzle-pkg/lib/schema/rss.ts
  6. 73
      packages/drizzle-pkg/migrations/0001_add-multitenant-content-rss.sql
  7. 793
      packages/drizzle-pkg/migrations/meta/0001_snapshot.json
  8. 7
      packages/drizzle-pkg/migrations/meta/_journal.json

7
packages/drizzle-pkg/database/sqlite/schema/auth.ts

@ -7,6 +7,13 @@ export const users = sqliteTable("users", {
nickname: text(), nickname: text(),
password: text().notNull(), password: text().notNull(),
avatar: text(), avatar: text(),
role: text().notNull().default("user"),
status: text().notNull().default("active"),
publicSlug: text("public_slug").unique(),
bioMarkdown: text("bio_markdown"),
bioVisibility: text("bio_visibility").notNull().default("private"),
socialLinksJson: text("social_links_json").notNull().default("[]"),
avatarVisibility: text("avatar_visibility").notNull().default("private"),
createdAt: integer("created_at", { mode: "timestamp_ms" }).defaultNow().notNull(), createdAt: integer("created_at", { mode: "timestamp_ms" }).defaultNow().notNull(),
updatedAt: integer("updated_at", { mode: "timestamp_ms" }) updatedAt: integer("updated_at", { mode: "timestamp_ms" })
.defaultNow() .defaultNow()

46
packages/drizzle-pkg/database/sqlite/schema/content.ts

@ -0,0 +1,46 @@
import { integer, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
import { users } from "./auth";
export const posts = sqliteTable(
"posts",
{
id: integer().primaryKey(),
userId: integer("user_id")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
title: text().notNull(),
slug: text().notNull(),
bodyMarkdown: text("body_markdown").notNull(),
excerpt: text().notNull(),
coverUrl: text("cover_url"),
tagsJson: text("tags_json").notNull().default("[]"),
publishedAt: integer("published_at", { mode: "timestamp_ms" }),
visibility: text().notNull().default("private"),
shareToken: text("share_token"),
createdAt: integer("created_at", { mode: "timestamp_ms" }).defaultNow().notNull(),
updatedAt: integer("updated_at", { mode: "timestamp_ms" })
.defaultNow()
.$onUpdate(() => new Date())
.notNull(),
},
(table) => [uniqueIndex("posts_user_id_slug_unique").on(table.userId, table.slug)],
);
export const timelineEvents = sqliteTable("timeline_events", {
id: integer().primaryKey(),
userId: integer("user_id")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
occurredOn: integer("occurred_on", { mode: "timestamp_ms" }).notNull(),
title: text().notNull(),
bodyMarkdown: text("body_markdown"),
linkUrl: text("link_url"),
visibility: text().notNull().default("private"),
shareToken: text("share_token"),
createdAt: integer("created_at", { mode: "timestamp_ms" }).defaultNow().notNull(),
updatedAt: integer("updated_at", { mode: "timestamp_ms" })
.defaultNow()
.$onUpdate(() => new Date())
.notNull(),
});

50
packages/drizzle-pkg/database/sqlite/schema/rss.ts

@ -0,0 +1,50 @@
import { sql } from "drizzle-orm";
import { integer, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
import { users } from "./auth";
export const rssFeeds = sqliteTable(
"rss_feeds",
{
id: integer().primaryKey(),
userId: integer("user_id")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
feedUrl: text("feed_url").notNull(),
title: text(),
siteUrl: text("site_url"),
lastFetchedAt: integer("last_fetched_at", { mode: "timestamp_ms" }),
lastError: text("last_error"),
pollIntervalMinutes: integer("poll_interval_minutes"),
createdAt: integer("created_at", { mode: "timestamp_ms" }).defaultNow().notNull(),
},
(table) => [uniqueIndex("rss_feeds_user_id_feed_url_unique").on(table.userId, table.feedUrl)],
);
export const rssItems = sqliteTable(
"rss_items",
{
id: integer().primaryKey(),
userId: integer("user_id")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
feedId: integer("feed_id")
.notNull()
.references(() => rssFeeds.id, { onDelete: "cascade" }),
guid: text(),
canonicalUrl: text("canonical_url").notNull(),
title: text(),
summary: text(),
contentSnippet: text("content_snippet"),
author: text(),
publishedAt: integer("published_at", { mode: "timestamp_ms" }),
visibility: text().notNull().default("private"),
shareToken: text("share_token"),
createdAt: integer("created_at", { mode: "timestamp_ms" }).defaultNow().notNull(),
},
(table) => [
uniqueIndex("rss_items_feed_id_guid_unique")
.on(table.feedId, table.guid)
.where(sql`${table.guid} IS NOT NULL`),
],
);

1
packages/drizzle-pkg/lib/schema/content.ts

@ -0,0 +1 @@
export { posts, timelineEvents } from "../../database/sqlite/schema/content";

1
packages/drizzle-pkg/lib/schema/rss.ts

@ -0,0 +1 @@
export { rssFeeds, rssItems } from "../../database/sqlite/schema/rss";

73
packages/drizzle-pkg/migrations/0001_add-multitenant-content-rss.sql

@ -0,0 +1,73 @@
CREATE TABLE `posts` (
`id` integer PRIMARY KEY NOT NULL,
`user_id` integer NOT NULL,
`title` text NOT NULL,
`slug` text NOT NULL,
`body_markdown` text NOT NULL,
`excerpt` text NOT NULL,
`cover_url` text,
`tags_json` text DEFAULT '[]' NOT NULL,
`published_at` integer,
`visibility` text DEFAULT 'private' NOT NULL,
`share_token` text,
`created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
`updated_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade
);
--> statement-breakpoint
CREATE UNIQUE INDEX `posts_user_id_slug_unique` ON `posts` (`user_id`,`slug`);--> statement-breakpoint
CREATE TABLE `timeline_events` (
`id` integer PRIMARY KEY NOT NULL,
`user_id` integer NOT NULL,
`occurred_on` integer NOT NULL,
`title` text NOT NULL,
`body_markdown` text,
`link_url` text,
`visibility` text DEFAULT 'private' NOT NULL,
`share_token` text,
`created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
`updated_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade
);
--> statement-breakpoint
CREATE TABLE `rss_feeds` (
`id` integer PRIMARY KEY NOT NULL,
`user_id` integer NOT NULL,
`feed_url` text NOT NULL,
`title` text,
`site_url` text,
`last_fetched_at` integer,
`last_error` text,
`poll_interval_minutes` integer,
`created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade
);
--> statement-breakpoint
CREATE UNIQUE INDEX `rss_feeds_user_id_feed_url_unique` ON `rss_feeds` (`user_id`,`feed_url`);--> statement-breakpoint
CREATE TABLE `rss_items` (
`id` integer PRIMARY KEY NOT NULL,
`user_id` integer NOT NULL,
`feed_id` integer NOT NULL,
`guid` text,
`canonical_url` text NOT NULL,
`title` text,
`summary` text,
`content_snippet` text,
`author` text,
`published_at` integer,
`visibility` text DEFAULT 'private' NOT NULL,
`share_token` text,
`created_at` integer DEFAULT (cast((julianday('now') - 2440587.5)*86400000 as integer)) NOT NULL,
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade,
FOREIGN KEY (`feed_id`) REFERENCES `rss_feeds`(`id`) ON UPDATE no action ON DELETE cascade
);
--> statement-breakpoint
CREATE UNIQUE INDEX `rss_items_feed_id_guid_unique` ON `rss_items` (`feed_id`,`guid`) WHERE "rss_items"."guid" IS NOT NULL;--> statement-breakpoint
ALTER TABLE `users` ADD `role` text DEFAULT 'user' NOT NULL;--> statement-breakpoint
ALTER TABLE `users` ADD `status` text DEFAULT 'active' NOT NULL;--> statement-breakpoint
ALTER TABLE `users` ADD `public_slug` text;--> statement-breakpoint
ALTER TABLE `users` ADD `bio_markdown` text;--> statement-breakpoint
ALTER TABLE `users` ADD `bio_visibility` text DEFAULT 'private' NOT NULL;--> statement-breakpoint
ALTER TABLE `users` ADD `social_links_json` text DEFAULT '[]' NOT NULL;--> statement-breakpoint
ALTER TABLE `users` ADD `avatar_visibility` text DEFAULT 'private' NOT NULL;--> statement-breakpoint
CREATE UNIQUE INDEX `users_public_slug_unique` ON `users` (`public_slug`);

793
packages/drizzle-pkg/migrations/meta/0001_snapshot.json

@ -0,0 +1,793 @@
{
"version": "6",
"dialect": "sqlite",
"id": "66f33657-5926-4ac6-a196-2d142081b192",
"prevId": "0c82e00e-7d76-4479-a196-ceb6eb02ad3f",
"tables": {
"sessions": {
"name": "sessions",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"user_id": {
"name": "user_id",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"expires_at": {
"name": "expires_at",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
}
},
"indexes": {
"sessions_user_id_idx": {
"name": "sessions_user_id_idx",
"columns": [
"user_id"
],
"isUnique": false
}
},
"foreignKeys": {
"sessions_user_id_users_id_fk": {
"name": "sessions_user_id_users_id_fk",
"tableFrom": "sessions",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"users": {
"name": "users",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"username": {
"name": "username",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"nickname": {
"name": "nickname",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"password": {
"name": "password",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"avatar": {
"name": "avatar",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"role": {
"name": "role",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'user'"
},
"status": {
"name": "status",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'active'"
},
"public_slug": {
"name": "public_slug",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"bio_markdown": {
"name": "bio_markdown",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"bio_visibility": {
"name": "bio_visibility",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'private'"
},
"social_links_json": {
"name": "social_links_json",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'[]'"
},
"avatar_visibility": {
"name": "avatar_visibility",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'private'"
},
"created_at": {
"name": "created_at",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
},
"updated_at": {
"name": "updated_at",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
}
},
"indexes": {
"users_username_unique": {
"name": "users_username_unique",
"columns": [
"username"
],
"isUnique": true
},
"users_public_slug_unique": {
"name": "users_public_slug_unique",
"columns": [
"public_slug"
],
"isUnique": true
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"app_configs": {
"name": "app_configs",
"columns": {
"key": {
"name": "key",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"value": {
"name": "value",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"value_type": {
"name": "value_type",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"updated_at": {
"name": "updated_at",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"user_configs": {
"name": "user_configs",
"columns": {
"user_id": {
"name": "user_id",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"key": {
"name": "key",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"value": {
"name": "value",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"value_type": {
"name": "value_type",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"updated_at": {
"name": "updated_at",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
}
},
"indexes": {
"user_configs_user_id_idx": {
"name": "user_configs_user_id_idx",
"columns": [
"user_id"
],
"isUnique": false
}
},
"foreignKeys": {
"user_configs_user_id_users_id_fk": {
"name": "user_configs_user_id_users_id_fk",
"tableFrom": "user_configs",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"user_configs_user_id_key_pk": {
"columns": [
"user_id",
"key"
],
"name": "user_configs_user_id_key_pk"
}
},
"uniqueConstraints": {},
"checkConstraints": {}
},
"posts": {
"name": "posts",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"user_id": {
"name": "user_id",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"title": {
"name": "title",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"slug": {
"name": "slug",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"body_markdown": {
"name": "body_markdown",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"excerpt": {
"name": "excerpt",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"cover_url": {
"name": "cover_url",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"tags_json": {
"name": "tags_json",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'[]'"
},
"published_at": {
"name": "published_at",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"visibility": {
"name": "visibility",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'private'"
},
"share_token": {
"name": "share_token",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
},
"updated_at": {
"name": "updated_at",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
}
},
"indexes": {
"posts_user_id_slug_unique": {
"name": "posts_user_id_slug_unique",
"columns": [
"user_id",
"slug"
],
"isUnique": true
}
},
"foreignKeys": {
"posts_user_id_users_id_fk": {
"name": "posts_user_id_users_id_fk",
"tableFrom": "posts",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"timeline_events": {
"name": "timeline_events",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"user_id": {
"name": "user_id",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"occurred_on": {
"name": "occurred_on",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"title": {
"name": "title",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"body_markdown": {
"name": "body_markdown",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"link_url": {
"name": "link_url",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"visibility": {
"name": "visibility",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'private'"
},
"share_token": {
"name": "share_token",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
},
"updated_at": {
"name": "updated_at",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
}
},
"indexes": {},
"foreignKeys": {
"timeline_events_user_id_users_id_fk": {
"name": "timeline_events_user_id_users_id_fk",
"tableFrom": "timeline_events",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"rss_feeds": {
"name": "rss_feeds",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"user_id": {
"name": "user_id",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"feed_url": {
"name": "feed_url",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"title": {
"name": "title",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"site_url": {
"name": "site_url",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"last_fetched_at": {
"name": "last_fetched_at",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"last_error": {
"name": "last_error",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"poll_interval_minutes": {
"name": "poll_interval_minutes",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
}
},
"indexes": {
"rss_feeds_user_id_feed_url_unique": {
"name": "rss_feeds_user_id_feed_url_unique",
"columns": [
"user_id",
"feed_url"
],
"isUnique": true
}
},
"foreignKeys": {
"rss_feeds_user_id_users_id_fk": {
"name": "rss_feeds_user_id_users_id_fk",
"tableFrom": "rss_feeds",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"rss_items": {
"name": "rss_items",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"user_id": {
"name": "user_id",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"feed_id": {
"name": "feed_id",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"guid": {
"name": "guid",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"canonical_url": {
"name": "canonical_url",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"title": {
"name": "title",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"summary": {
"name": "summary",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"content_snippet": {
"name": "content_snippet",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"author": {
"name": "author",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"published_at": {
"name": "published_at",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"visibility": {
"name": "visibility",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'private'"
},
"share_token": {
"name": "share_token",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(cast((julianday('now') - 2440587.5)*86400000 as integer))"
}
},
"indexes": {
"rss_items_feed_id_guid_unique": {
"name": "rss_items_feed_id_guid_unique",
"columns": [
"feed_id",
"guid"
],
"isUnique": true,
"where": "\"rss_items\".\"guid\" IS NOT NULL"
}
},
"foreignKeys": {
"rss_items_user_id_users_id_fk": {
"name": "rss_items_user_id_users_id_fk",
"tableFrom": "rss_items",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"rss_items_feed_id_rss_feeds_id_fk": {
"name": "rss_items_feed_id_rss_feeds_id_fk",
"tableFrom": "rss_items",
"tableTo": "rss_feeds",
"columnsFrom": [
"feed_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
}
},
"views": {},
"enums": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"internal": {
"indexes": {}
}
}

7
packages/drizzle-pkg/migrations/meta/_journal.json

@ -8,6 +8,13 @@
"when": 1776386788654, "when": 1776386788654,
"tag": "0000_init", "tag": "0000_init",
"breakpoints": true "breakpoints": true
},
{
"idx": 1,
"version": "6",
"when": 1776457621565,
"tag": "0001_add-multitenant-content-rss",
"breakpoints": true
} }
] ]
} }
Loading…
Cancel
Save