diff --git a/src/db/migrations/0012_magenta_captain_marvel.sql b/src/db/migrations/0012_magenta_captain_marvel.sql new file mode 100644 index 0000000..ccb573b --- /dev/null +++ b/src/db/migrations/0012_magenta_captain_marvel.sql @@ -0,0 +1,3 @@ +ALTER TABLE "sites" ALTER COLUMN "freebie_name" SET DEFAULT 'Our newsletter';--> statement-breakpoint +ALTER TABLE "sites" ADD COLUMN "use_contact_page" boolean DEFAULT false;--> statement-breakpoint +ALTER TABLE "sites" ADD COLUMN "contact_email" text; \ No newline at end of file diff --git a/src/db/migrations/0013_lucky_vulture.sql b/src/db/migrations/0013_lucky_vulture.sql new file mode 100644 index 0000000..8725f38 --- /dev/null +++ b/src/db/migrations/0013_lucky_vulture.sql @@ -0,0 +1,2 @@ +ALTER TABLE "sites" ADD COLUMN "use_about_page" boolean DEFAULT true;--> statement-breakpoint +ALTER TABLE "sites" ADD COLUMN "about_text" text; \ No newline at end of file diff --git a/src/db/migrations/meta/0012_snapshot.json b/src/db/migrations/meta/0012_snapshot.json new file mode 100644 index 0000000..3903878 --- /dev/null +++ b/src/db/migrations/meta/0012_snapshot.json @@ -0,0 +1,499 @@ +{ + "id": "dcc6e5bd-8fea-4462-8f49-5cfc09408ab7", + "prevId": "1b69d63a-4517-42bc-aa1f-0ae6ed4ac685", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.articles": { + "name": "articles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "site_id": { + "name": "site_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_video_id": { + "name": "source_video_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "seo_slug": { + "name": "seo_slug", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_public": { + "name": "is_public", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "views": { + "name": "views", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "seo_title": { + "name": "seo_title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "seo_description": { + "name": "seo_description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "excerp": { + "name": "excerp", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "article_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'queued'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "articles_site_id_sites_id_fk": { + "name": "articles_site_id_sites_id_fk", + "tableFrom": "articles", + "tableTo": "sites", + "columnsFrom": [ + "site_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.sessions": { + "name": "sessions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "google_access_token": { + "name": "google_access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "google_refresh_token": { + "name": "google_refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", + "tableFrom": "sessions", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.signups": { + "name": "signups", + "schema": "", + "columns": { + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "site_id": { + "name": "site_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "signups_site_id_sites_id_fk": { + "name": "signups_site_id_sites_id_fk", + "tableFrom": "signups", + "tableTo": "sites", + "columnsFrom": [ + "site_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.sites": { + "name": "sites", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "primary_color_hex": { + "name": "primary_color_hex", + "type": "varchar(6)", + "primaryKey": false, + "notNull": true, + "default": "'c4ced4'" + }, + "secondary_color_hex": { + "name": "secondary_color_hex", + "type": "varchar(6)", + "primaryKey": false, + "notNull": true, + "default": "'27251f'" + }, + "text_color_hex": { + "name": "text_color_hex", + "type": "varchar(6)", + "primaryKey": false, + "notNull": true, + "default": "'ffffff'" + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'The best blog in the world!'" + }, + "subtitle": { + "name": "subtitle", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'Some extra info about the best blog in the world!'" + }, + "domain": { + "name": "domain", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "NULL" + }, + "send_freebie": { + "name": "send_freebie", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "freebie_name": { + "name": "freebie_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'Our newsletter'" + }, + "freebie_url": { + "name": "freebie_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "freebie_text": { + "name": "freebie_text", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "freebie_image_url": { + "name": "freebie_image_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "subdomain_slug": { + "name": "subdomain_slug", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "social_medias": { + "name": "social_medias", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "auto_publish": { + "name": "auto_publish", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "pubsub_expiry": { + "name": "pubsub_expiry", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "use_contact_page": { + "name": "use_contact_page", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "contact_email": { + "name": "contact_email", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "sites_user_id_users_id_fk": { + "name": "sites_user_id_users_id_fk", + "tableFrom": "sites", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sites_domain_unique": { + "name": "sites_domain_unique", + "nullsNotDistinct": false, + "columns": [ + "domain" + ] + } + } + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "google_id": { + "name": "google_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_id": { + "name": "stripe_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "channel_id": { + "name": "channel_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uploads_playlist_id": { + "name": "uploads_playlist_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subscription_tier": { + "name": "subscription_tier", + "type": "subscription_tier", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'free'" + }, + "tokens": { + "name": "tokens", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 200 + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.waitlist": { + "name": "waitlist", + "schema": "", + "columns": { + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": { + "public.article_status": { + "name": "article_status", + "schema": "public", + "values": [ + "queued", + "transcribing", + "generating", + "done", + "error" + ] + }, + "public.subscription_tier": { + "name": "subscription_tier", + "schema": "public", + "values": [ + "free", + "basic", + "pro", + "enterprise" + ] + } + }, + "schemas": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/src/db/migrations/meta/0013_snapshot.json b/src/db/migrations/meta/0013_snapshot.json new file mode 100644 index 0000000..e051af1 --- /dev/null +++ b/src/db/migrations/meta/0013_snapshot.json @@ -0,0 +1,512 @@ +{ + "id": "de65dcf5-f6de-434b-80b6-ba199df3a96a", + "prevId": "dcc6e5bd-8fea-4462-8f49-5cfc09408ab7", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.articles": { + "name": "articles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "site_id": { + "name": "site_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_video_id": { + "name": "source_video_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "seo_slug": { + "name": "seo_slug", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_public": { + "name": "is_public", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "views": { + "name": "views", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "seo_title": { + "name": "seo_title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "seo_description": { + "name": "seo_description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "excerp": { + "name": "excerp", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "article_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'queued'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "articles_site_id_sites_id_fk": { + "name": "articles_site_id_sites_id_fk", + "tableFrom": "articles", + "tableTo": "sites", + "columnsFrom": [ + "site_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.sessions": { + "name": "sessions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "google_access_token": { + "name": "google_access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "google_refresh_token": { + "name": "google_refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", + "tableFrom": "sessions", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.signups": { + "name": "signups", + "schema": "", + "columns": { + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "site_id": { + "name": "site_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "signups_site_id_sites_id_fk": { + "name": "signups_site_id_sites_id_fk", + "tableFrom": "signups", + "tableTo": "sites", + "columnsFrom": [ + "site_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.sites": { + "name": "sites", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "primary_color_hex": { + "name": "primary_color_hex", + "type": "varchar(6)", + "primaryKey": false, + "notNull": true, + "default": "'c4ced4'" + }, + "secondary_color_hex": { + "name": "secondary_color_hex", + "type": "varchar(6)", + "primaryKey": false, + "notNull": true, + "default": "'27251f'" + }, + "text_color_hex": { + "name": "text_color_hex", + "type": "varchar(6)", + "primaryKey": false, + "notNull": true, + "default": "'ffffff'" + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'The best blog in the world!'" + }, + "subtitle": { + "name": "subtitle", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'Some extra info about the best blog in the world!'" + }, + "domain": { + "name": "domain", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "NULL" + }, + "send_freebie": { + "name": "send_freebie", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "freebie_name": { + "name": "freebie_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'Our newsletter'" + }, + "freebie_url": { + "name": "freebie_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "freebie_text": { + "name": "freebie_text", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "freebie_image_url": { + "name": "freebie_image_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "subdomain_slug": { + "name": "subdomain_slug", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "social_medias": { + "name": "social_medias", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "auto_publish": { + "name": "auto_publish", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "pubsub_expiry": { + "name": "pubsub_expiry", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "use_contact_page": { + "name": "use_contact_page", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "contact_email": { + "name": "contact_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "use_about_page": { + "name": "use_about_page", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "about_text": { + "name": "about_text", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "sites_user_id_users_id_fk": { + "name": "sites_user_id_users_id_fk", + "tableFrom": "sites", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sites_domain_unique": { + "name": "sites_domain_unique", + "nullsNotDistinct": false, + "columns": [ + "domain" + ] + } + } + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "google_id": { + "name": "google_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stripe_id": { + "name": "stripe_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "channel_id": { + "name": "channel_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uploads_playlist_id": { + "name": "uploads_playlist_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subscription_tier": { + "name": "subscription_tier", + "type": "subscription_tier", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'free'" + }, + "tokens": { + "name": "tokens", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 200 + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.waitlist": { + "name": "waitlist", + "schema": "", + "columns": { + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": { + "public.article_status": { + "name": "article_status", + "schema": "public", + "values": [ + "queued", + "transcribing", + "generating", + "done", + "error" + ] + }, + "public.subscription_tier": { + "name": "subscription_tier", + "schema": "public", + "values": [ + "free", + "basic", + "pro", + "enterprise" + ] + } + }, + "schemas": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/src/db/migrations/meta/_journal.json b/src/db/migrations/meta/_journal.json index aa9fae5..a91161e 100644 --- a/src/db/migrations/meta/_journal.json +++ b/src/db/migrations/meta/_journal.json @@ -85,6 +85,20 @@ "when": 1719007763731, "tag": "0011_normal_thunderball", "breakpoints": true + }, + { + "idx": 12, + "version": "7", + "when": 1719133327271, + "tag": "0012_magenta_captain_marvel", + "breakpoints": true + }, + { + "idx": 13, + "version": "7", + "when": 1719134353536, + "tag": "0013_lucky_vulture", + "breakpoints": true } ] } \ No newline at end of file diff --git a/src/db/schemas.js b/src/db/schemas.js index eff9887..03a792a 100644 --- a/src/db/schemas.js +++ b/src/db/schemas.js @@ -47,7 +47,7 @@ export const sites = pgTable("sites", { subtitle: text("subtitle").default("Some extra info about the best blog in the world!"), domain: text("domain").default(sql`NULL`).unique(), use_freebie: boolean("send_freebie").default(false), - freebie_name: text("freebie_name").default(""), + freebie_title: text("freebie_name").default("Our newsletter"), freebie_url: text("freebie_url").default(""), freebie_text: text("freebie_text").default(""), freebie_image_url: text("freebie_image_url").default(""), @@ -56,7 +56,11 @@ export const sites = pgTable("sites", { }), social_medias: jsonb("social_medias"), auto_publish: boolean("auto_publish").default(false), - pubsub_expiry: timestamp("pubsub_expiry") + pubsub_expiry: timestamp("pubsub_expiry"), + use_contact_page: boolean("use_contact_page").default(false), + contact_email: text("contact_email"), + use_about_page: boolean("use_about_page").default(true), + about_text: text("about_text") }); export const articles = pgTable("articles", { diff --git a/src/routes/blog.js b/src/routes/blog.js index 4ba0939..5a43988 100644 --- a/src/routes/blog.js +++ b/src/routes/blog.js @@ -77,7 +77,7 @@ export const blogRoutes = (fastify, _, done) => { views: articlesTable.views, is_public: articlesTable.is_public, created_at: articlesTable.created_at, - }).from(articlesTable).where(and(eq(articlesTable.status, "done"), clause)).limit(10).offset(request.query.offset || 0).orderBy(desc(articlesTable.created_at)); + }).from(articlesTable).where(and(eq(articlesTable.status, "done"), clause)).limit(3).offset(request.query.offset || 0).orderBy(desc(articlesTable.created_at)); const [{ total }] = await db.select({ total: sql`COUNT(*)` @@ -162,7 +162,6 @@ export const blogRoutes = (fastify, _, done) => { return; } - await sendFreebie(req.body.email, req.body.site_id) reply.send({ diff --git a/src/routes/dashboard.js b/src/routes/dashboard.js index 3e26d29..735eb4d 100644 --- a/src/routes/dashboard.js +++ b/src/routes/dashboard.js @@ -364,7 +364,7 @@ export const dashboardRoutes = (fastify, _, done) => { use_freebie: { type: "boolean" }, - freebie_name: { + freebie_title: { type: ["string", "null"] }, freebie_url: { @@ -389,6 +389,13 @@ export const dashboardRoutes = (fastify, _, done) => { }, auto_publish: { type: "boolean" + }, + use_contact_page: { + type: "boolean" + }, + contact_email: { + type: "string", + format: "email" } }, required: ["id"]