diff --git a/src/config/schema.sql b/src/config/schema.sql new file mode 100644 index 0000000..ac5f4ca --- /dev/null +++ b/src/config/schema.sql @@ -0,0 +1,2228 @@ +-- +-- PostgreSQL database dump +-- + +\restrict VhNY3y2jfbhtHWUJNX17PN7SRgHPDQoK22OdEvgq8EbNJ3oFJFZi6W1o1ShNkWQ + +-- Dumped from database version 16.14 (Ubuntu 16.14-0ubuntu0.24.04.1) +-- Dumped by pg_dump version 16.14 (Ubuntu 16.14-0ubuntu0.24.04.1) + +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET xmloption = content; +SET client_min_messages = warning; +SET row_security = off; + +SET default_tablespace = ''; + +SET default_table_access_method = heap; + +-- +-- Name: ai_usage; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.ai_usage ( + id bigint NOT NULL, + service text NOT NULL, + provider text NOT NULL, + request_type text NOT NULL, + model text NOT NULL, + user_id integer, + prompt_tokens integer, + completion_tokens integer, + total_tokens integer, + image_count integer, + cost_rub numeric(10,4), + request_id text, + meta jsonb, + duration_ms integer, + succeeded boolean DEFAULT true NOT NULL, + error_message text, + created_at timestamp with time zone DEFAULT now() NOT NULL +); + + +-- +-- Name: ai_usage_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.ai_usage_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: ai_usage_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.ai_usage_id_seq OWNED BY public.ai_usage.id; + + +-- +-- Name: app_settings; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.app_settings ( + key text NOT NULL, + value text, + description text, + category text DEFAULT 'general'::text NOT NULL, + is_secret boolean DEFAULT false NOT NULL, + updated_at timestamp with time zone DEFAULT now() +); + + +-- +-- Name: articles; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.articles ( + id integer NOT NULL, + slug character varying(255) NOT NULL, + title character varying(500) NOT NULL, + excerpt text, + content text NOT NULL, + cover_url text, + tags jsonb DEFAULT '[]'::jsonb, + author character varying(100) DEFAULT 'ZeroPost AI'::character varying, + reading_time integer, + status character varying(20) DEFAULT 'published'::character varying, + views integer DEFAULT 0, + seo_title character varying(500), + seo_descr text, + job_id integer, + published_at timestamp with time zone DEFAULT now(), + created_at timestamp with time zone DEFAULT now(), + updated_at timestamp with time zone DEFAULT now(), + category character varying(50) DEFAULT 'ai-tools'::character varying, + source_topic text, + topic_hash character varying(64) +); + + +-- +-- Name: articles_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.articles_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: articles_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.articles_id_seq OWNED BY public.articles.id; + + +-- +-- Name: autogen_settings; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.autogen_settings ( + id integer NOT NULL, + category character varying(50) NOT NULL, + enabled boolean DEFAULT true, + per_day integer DEFAULT 1, + last_run_at timestamp with time zone, + next_run_at timestamp with time zone, + run_hour integer DEFAULT 8, + run_minute integer DEFAULT 0 +); + + +-- +-- Name: autogen_settings_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.autogen_settings_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: autogen_settings_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.autogen_settings_id_seq OWNED BY public.autogen_settings.id; + + +-- +-- Name: blog_topics; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.blog_topics ( + id integer NOT NULL, + category character varying(50) NOT NULL, + topic text NOT NULL, + tags text[] DEFAULT '{}'::text[], + is_used boolean DEFAULT false, + used_at timestamp with time zone, + source character varying(16) DEFAULT 'manual'::character varying, + priority integer DEFAULT 5, + created_at timestamp with time zone DEFAULT now() +); + + +-- +-- Name: blog_topics_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.blog_topics_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: blog_topics_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.blog_topics_id_seq OWNED BY public.blog_topics.id; + + +-- +-- Name: categories; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.categories ( + id integer NOT NULL, + slug character varying(50) NOT NULL, + name character varying(100) NOT NULL, + description text, + color character varying(20) DEFAULT 'emerald'::character varying, + icon character varying(10) DEFAULT 'πŸ€–'::character varying, + sort_order integer DEFAULT 0 +); + + +-- +-- Name: categories_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.categories_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: categories_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.categories_id_seq OWNED BY public.categories.id; + + +-- +-- Name: channel_schedule; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.channel_schedule ( + channel_id integer NOT NULL, + posts_per_day integer DEFAULT 1, + time_slots jsonb DEFAULT '[]'::jsonb, + timezone character varying(50) DEFAULT 'Europe/Moscow'::character varying, + rubrics jsonb DEFAULT '[]'::jsonb, + sources jsonb DEFAULT '[]'::jsonb, + auto_publish boolean DEFAULT false, + updated_at timestamp with time zone DEFAULT now() +); + + +-- +-- Name: channel_stats; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.channel_stats ( + id integer NOT NULL, + channel_id integer NOT NULL, + captured_at timestamp with time zone DEFAULT now() NOT NULL, + members integer, + views_last_post integer, + avg_views_30d integer, + err_percent numeric(5,2) +); + + +-- +-- Name: TABLE channel_stats; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON TABLE public.channel_stats IS 'Π˜ΡΡ‚ΠΎΡ€ΠΈΡ ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊ ΠΊΠ°Π½Π°Π»ΠΎΠ²: подписчики, просмотры, ERR'; + + +-- +-- Name: channel_stats_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.channel_stats_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: channel_stats_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.channel_stats_id_seq OWNED BY public.channel_stats.id; + + +-- +-- Name: channel_style; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.channel_style ( + channel_id integer NOT NULL, + tone character varying(50) DEFAULT 'friendly'::character varying, + tone_custom text, + formality character varying(20) DEFAULT 'informal'::character varying, + humor character varying(20) DEFAULT 'moderate'::character varying, + post_length character varying(20) DEFAULT 'medium'::character varying, + structure character varying(50) DEFAULT 'mixed'::character varying, + emoji_level character varying(20) DEFAULT 'moderate'::character varying, + hashtags_mode character varying(20) DEFAULT 'end'::character varying, + cta_mode character varying(20) DEFAULT 'sometimes'::character varying, + example_posts jsonb DEFAULT '[]'::jsonb, + banned_words jsonb DEFAULT '[]'::jsonb, + banned_topics jsonb DEFAULT '[]'::jsonb, + expertise jsonb DEFAULT '[]'::jsonb, + updated_at timestamp with time zone DEFAULT now(), + image_enabled boolean DEFAULT false, + image_style character varying(255) DEFAULT 'flat-illustration'::character varying, + image_palette character varying(30) DEFAULT 'auto'::character varying, + image_custom_colors text, + image_prompt_instructions text, + image_rubrics jsonb DEFAULT '[]'::jsonb, + last_rubrics_used jsonb DEFAULT '[]'::jsonb +); + + +-- +-- Name: channel_topics; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.channel_topics ( + id bigint NOT NULL, + channel_id integer NOT NULL, + topic text NOT NULL, + keywords text[] DEFAULT '{}'::text[], + is_used boolean DEFAULT false NOT NULL, + used_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL +); + + +-- +-- Name: channel_topics_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.channel_topics_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: channel_topics_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.channel_topics_id_seq OWNED BY public.channel_topics.id; + + +-- +-- Name: channels; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.channels ( + id integer NOT NULL, + user_id integer NOT NULL, + name character varying(255) NOT NULL, + tg_channel_id character varying(255), + tg_username character varying(255), + bot_token text, + niche text, + audience text, + goal character varying(255) DEFAULT 'educational'::character varying, + language character varying(10) DEFAULT 'ru'::character varying, + region character varying(50) DEFAULT 'ru'::character varying, + is_active boolean DEFAULT true, + created_at timestamp with time zone DEFAULT now(), + updated_at timestamp with time zone DEFAULT now(), + platform character varying(20) DEFAULT 'telegram'::character varying, + vk_group_id character varying(255), + vk_access_token text, + max_channel_id character varying(255), + max_access_token text, + is_system boolean DEFAULT false, + photo_search_profile_id integer, + auto_publish_enabled boolean DEFAULT false NOT NULL, + auto_publish_categories text[] DEFAULT '{}'::text[] NOT NULL, + auto_publish_delay_min integer DEFAULT 0 NOT NULL, + auto_publish_template text, + auto_publish_with_cover boolean DEFAULT true NOT NULL, + auto_publish_button_text text, + auto_publish_image_source text DEFAULT 'cover'::text NOT NULL, + ai_style_prompt text, + image_quality character varying(16) DEFAULT 'standard'::character varying, + tg_webhook_enabled boolean DEFAULT false, + topics_min_stock integer DEFAULT 5, + auto_draft_enabled boolean DEFAULT false, + auto_draft_count integer DEFAULT 3, + auto_draft_time character varying(5) DEFAULT '08:00'::character varying, + image_enabled boolean DEFAULT true, + CONSTRAINT channels_auto_publish_image_source_check CHECK ((auto_publish_image_source = ANY (ARRAY['cover'::text, 'zero'::text, 'alternating'::text, 'none'::text]))) +); + + +-- +-- Name: COLUMN channels.auto_publish_enabled; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.channels.auto_publish_enabled IS 'Π’ΠΊΠ»ΡŽΡ‡Π΅Π½Π° Π»ΠΈ автопубликация статСй Π² этот ΠΊΠ°Π½Π°Π»'; + + +-- +-- Name: COLUMN channels.auto_publish_categories; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.channels.auto_publish_categories IS 'ΠšΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ статСй, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠΏΠ°Π΄Π°ΡŽΡ‚ Π² этот ΠΊΠ°Π½Π°Π» автоматичСски. ΠŸΡƒΡΡ‚ΠΎΠΉ массив = всС.'; + + +-- +-- Name: COLUMN channels.auto_publish_delay_min; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.channels.auto_publish_delay_min IS 'Π—Π°Π΄Π΅Ρ€ΠΆΠΊΠ° Π² ΠΌΠΈΠ½ΡƒΡ‚Π°Ρ… послС publish_at ΡΡ‚Π°Ρ‚ΡŒΠΈ. 0 = сразу Π½Π° блиТайший слот.'; + + +-- +-- Name: COLUMN channels.auto_publish_template; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.channels.auto_publish_template IS 'Π¨Π°Π±Π»ΠΎΠ½ поста. ΠŸΠ»Π΅ΠΉΡΡ…ΠΎΠ»Π΄Π΅Ρ€Ρ‹: {title} {excerpt} {url} {category}. Если NULL β€” Π΄Π΅Ρ„ΠΎΠ»Ρ‚.'; + + +-- +-- Name: COLUMN channels.auto_publish_with_cover; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.channels.auto_publish_with_cover IS 'ΠŸΡ€ΠΈΠΊΡ€Π΅ΠΏΠ»ΡΡ‚ΡŒ cover_url ΡΡ‚Π°Ρ‚ΡŒΠΈ ΠΊ посту'; + + +-- +-- Name: COLUMN channels.auto_publish_button_text; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.channels.auto_publish_button_text IS 'ВСкст inline-ΠΊΠ½ΠΎΠΏΠΊΠΈ Π² TG (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Β«πŸ“– Π§ΠΈΡ‚Π°Ρ‚ΡŒ Π½Π° сайтС β†’Β»). Для VK/MAX автоматичСски вставляСтся Π² тСкст.'; + + +-- +-- Name: COLUMN channels.auto_publish_image_source; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.channels.auto_publish_image_source IS 'cover = ΠΎΠ±Π»ΠΎΠΆΠΊΠ° ΡΡ‚Π°Ρ‚ΡŒΠΈ, zero = ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΡ Π—Π΅Ρ€ΠΎ ΠΏΠΎ ΠΏΠΎΠ·Π΅, none = Π±Π΅Π· ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ'; + + +-- +-- Name: channels_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.channels_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: channels_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.channels_id_seq OWNED BY public.channels.id; + + +-- +-- Name: content_queue; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.content_queue ( + id integer NOT NULL, + category character varying(50) NOT NULL, + topic text NOT NULL, + keywords jsonb DEFAULT '[]'::jsonb, + tags jsonb DEFAULT '[]'::jsonb, + priority integer DEFAULT 5, + status character varying(20) DEFAULT 'pending'::character varying, + article_id integer, + created_at timestamp with time zone DEFAULT now(), + processed_at timestamp with time zone +); + + +-- +-- Name: content_queue_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.content_queue_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: content_queue_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.content_queue_id_seq OWNED BY public.content_queue.id; + + +-- +-- Name: credit_costs; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.credit_costs ( + operation character varying(64) NOT NULL, + credits integer NOT NULL, + description text +); + + +-- +-- Name: editor_notes; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.editor_notes ( + id integer NOT NULL, + title character varying(255), + content text NOT NULL, + author character varying(100) DEFAULT 'Π Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€'::character varying, + tags jsonb DEFAULT '[]'::jsonb, + is_pinned boolean DEFAULT false, + is_published boolean DEFAULT true, + created_at timestamp with time zone DEFAULT now(), + updated_at timestamp with time zone DEFAULT now() +); + + +-- +-- Name: editor_notes_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.editor_notes_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: editor_notes_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.editor_notes_id_seq OWNED BY public.editor_notes.id; + + +-- +-- Name: generation_jobs; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.generation_jobs ( + id integer NOT NULL, + user_id integer, + channel_id integer, + type character varying(50) NOT NULL, + topic text, + rubric character varying(255), + prompt_debug text, + result text, + tokens_in integer, + tokens_out integer, + cost_cents integer DEFAULT 0, + status character varying(20) DEFAULT 'pending'::character varying, + error text, + metadata jsonb DEFAULT '{}'::jsonb, + created_at timestamp with time zone DEFAULT now(), + updated_at timestamp with time zone DEFAULT now() +); + + +-- +-- Name: generation_jobs_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.generation_jobs_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: generation_jobs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.generation_jobs_id_seq OWNED BY public.generation_jobs.id; + + +-- +-- Name: inbox_messages; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.inbox_messages ( + id bigint NOT NULL, + channel_id integer NOT NULL, + platform character varying(16) DEFAULT 'telegram'::character varying NOT NULL, + external_msg_id character varying(128), + from_user_id character varying(128), + from_username character varying(128), + from_name character varying(255), + reply_to_msg_id character varying(128), + text text NOT NULL, + raw jsonb DEFAULT '{}'::jsonb, + ai_type character varying(32), + ai_reply text, + ai_processed_at timestamp with time zone, + status character varying(16) DEFAULT 'new'::character varying NOT NULL, + replied_text text, + replied_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL +); + + +-- +-- Name: inbox_messages_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.inbox_messages_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: inbox_messages_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.inbox_messages_id_seq OWNED BY public.inbox_messages.id; + + +-- +-- Name: payment_orders; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.payment_orders ( + id bigint NOT NULL, + user_id integer NOT NULL, + plan_code character varying(32) NOT NULL, + yukassa_payment_id character varying(128), + amount_rub integer NOT NULL, + status character varying(32) DEFAULT 'pending'::character varying NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL +); + + +-- +-- Name: payment_orders_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.payment_orders_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: payment_orders_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.payment_orders_id_seq OWNED BY public.payment_orders.id; + + +-- +-- Name: photo_search_profiles; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.photo_search_profiles ( + id integer NOT NULL, + slug text NOT NULL, + name text NOT NULL, + description text, + domains text[] DEFAULT '{}'::text[] NOT NULL, + created_at timestamp with time zone DEFAULT now(), + updated_at timestamp with time zone DEFAULT now() +); + + +-- +-- Name: photo_search_profiles_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.photo_search_profiles_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: photo_search_profiles_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.photo_search_profiles_id_seq OWNED BY public.photo_search_profiles.id; + + +-- +-- Name: plans; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.plans ( + id integer NOT NULL, + code character varying(32) NOT NULL, + name character varying(64) NOT NULL, + price_rub integer DEFAULT 0 NOT NULL, + credits_month integer DEFAULT 0 NOT NULL, + channels_max integer DEFAULT 1 NOT NULL, + features jsonb DEFAULT '{}'::jsonb, + is_active boolean DEFAULT true, + sort_order integer DEFAULT 0 +); + + +-- +-- Name: plans_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.plans_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: plans_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.plans_id_seq OWNED BY public.plans.id; + + +-- +-- Name: post_drafts; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.post_drafts ( + id bigint NOT NULL, + channel_id integer NOT NULL, + user_id integer, + topic text, + text text NOT NULL, + image_url text, + image_local text, + status character varying(16) DEFAULT 'pending'::character varying NOT NULL, + scheduled_at timestamp with time zone, + gen_job_ids integer[], + created_at timestamp with time zone DEFAULT now() NOT NULL, + reviewed_at timestamp with time zone +); + + +-- +-- Name: post_drafts_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.post_drafts_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: post_drafts_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.post_drafts_id_seq OWNED BY public.post_drafts.id; + + +-- +-- Name: post_metrics; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.post_metrics ( + id integer NOT NULL, + post_id integer, + user_post_id integer, + captured_at timestamp with time zone DEFAULT now() NOT NULL, + views integer DEFAULT 0, + forwards integer DEFAULT 0, + reactions jsonb DEFAULT '{}'::jsonb, + CONSTRAINT chk_one_source CHECK (((((post_id IS NOT NULL))::integer + ((user_post_id IS NOT NULL))::integer) = 1)) +); + + +-- +-- Name: post_metrics_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.post_metrics_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: post_metrics_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.post_metrics_id_seq OWNED BY public.post_metrics.id; + + +-- +-- Name: posts; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.posts ( + id integer NOT NULL, + channel_id integer, + job_id integer, + content text NOT NULL, + image_url text, + status character varying(20) DEFAULT 'draft'::character varying, + scheduled_at timestamp with time zone, + published_at timestamp with time zone, + tg_message_id bigint, + metadata jsonb DEFAULT '{}'::jsonb, + created_at timestamp with time zone DEFAULT now(), + updated_at timestamp with time zone DEFAULT now(), + views integer DEFAULT 0, + forwards integer DEFAULT 0, + reactions jsonb DEFAULT '{}'::jsonb, + metrics_at timestamp with time zone +); + + +-- +-- Name: posts_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.posts_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: posts_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.posts_id_seq OWNED BY public.posts.id; + + +-- +-- Name: promo_codes; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.promo_codes ( + id integer NOT NULL, + code character varying(32) NOT NULL, + type character varying(16) DEFAULT 'credits'::character varying NOT NULL, + value integer NOT NULL, + max_uses integer DEFAULT 1, + used_count integer DEFAULT 0, + expires_at timestamp with time zone, + is_active boolean DEFAULT true, + description text, + created_at timestamp with time zone DEFAULT now() +); + + +-- +-- Name: promo_codes_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.promo_codes_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: promo_codes_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.promo_codes_id_seq OWNED BY public.promo_codes.id; + + +-- +-- Name: promo_usages; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.promo_usages ( + id bigint NOT NULL, + code_id integer NOT NULL, + user_id integer NOT NULL, + used_at timestamp with time zone DEFAULT now() +); + + +-- +-- Name: promo_usages_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.promo_usages_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: promo_usages_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.promo_usages_id_seq OWNED BY public.promo_usages.id; + + +-- +-- Name: publish_slots; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.publish_slots ( + id integer NOT NULL, + channel_id integer, + slot_hour integer NOT NULL, + slot_minute integer NOT NULL, + enabled boolean DEFAULT true, + label character varying(50), + sort_order integer DEFAULT 0 +); + + +-- +-- Name: publish_slots_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.publish_slots_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: publish_slots_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.publish_slots_id_seq OWNED BY public.publish_slots.id; + + +-- +-- Name: scheduled_posts; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.scheduled_posts ( + id integer NOT NULL, + channel_id integer, + article_id integer, + custom_text text, + status character varying(20) DEFAULT 'pending'::character varying, + scheduled_at timestamp with time zone NOT NULL, + published_at timestamp with time zone, + error text, + created_at timestamp with time zone DEFAULT now(), + cover_regen_attempts integer DEFAULT 0, + post_type character varying(16) DEFAULT 'article'::character varying, + meta jsonb DEFAULT '{}'::jsonb +); + + +-- +-- Name: scheduled_posts_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.scheduled_posts_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: scheduled_posts_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.scheduled_posts_id_seq OWNED BY public.scheduled_posts.id; + + +-- +-- Name: series; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.series ( + id integer NOT NULL, + slug character varying(120) NOT NULL, + title character varying(255) NOT NULL, + intro text, + icon character varying(40), + color character varying(20) DEFAULT 'emerald'::character varying, + article_ids jsonb DEFAULT '[]'::jsonb, + is_featured boolean DEFAULT false, + sort_order integer DEFAULT 0, + created_at timestamp with time zone DEFAULT now(), + updated_at timestamp with time zone DEFAULT now() +); + + +-- +-- Name: series_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.series_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: series_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.series_id_seq OWNED BY public.series.id; + + +-- +-- Name: user_balance; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.user_balance ( + user_id integer NOT NULL, + credits integer DEFAULT 0 NOT NULL, + credits_monthly_reset integer DEFAULT 0 NOT NULL, + reset_at timestamp with time zone, + updated_at timestamp with time zone DEFAULT now() NOT NULL +); + + +-- +-- Name: user_posts; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.user_posts ( + id integer NOT NULL, + user_id integer NOT NULL, + channel_id integer, + content text NOT NULL, + image_url text, + topic text, + status character varying(20) DEFAULT 'draft'::character varying, + scheduled_at timestamp with time zone, + published_at timestamp with time zone, + tg_message_id integer, + error text, + created_at timestamp with time zone DEFAULT now(), + updated_at timestamp with time zone DEFAULT now(), + image_credit jsonb, + views integer DEFAULT 0, + forwards integer DEFAULT 0, + reactions jsonb DEFAULT '{}'::jsonb, + metrics_at timestamp with time zone +); + + +-- +-- Name: COLUMN user_posts.image_credit; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.user_posts.image_credit IS 'Атрибуция Ρ„ΠΎΡ‚ΠΎ ΠΈΠ· photo-search: { domain, sourceUrl, title }'; + + +-- +-- Name: user_posts_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.user_posts_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: user_posts_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.user_posts_id_seq OWNED BY public.user_posts.id; + + +-- +-- Name: user_subscriptions; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.user_subscriptions ( + id integer NOT NULL, + user_id integer NOT NULL, + plan_id integer NOT NULL, + status character varying(16) DEFAULT 'active'::character varying NOT NULL, + started_at timestamp with time zone DEFAULT now() NOT NULL, + expires_at timestamp with time zone, + yukassa_sub_id character varying(128), + created_at timestamp with time zone DEFAULT now() NOT NULL +); + + +-- +-- Name: user_subscriptions_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.user_subscriptions_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: user_subscriptions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.user_subscriptions_id_seq OWNED BY public.user_subscriptions.id; + + +-- +-- Name: user_transactions; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.user_transactions ( + id bigint NOT NULL, + user_id integer NOT NULL, + type character varying(32) NOT NULL, + amount integer NOT NULL, + balance_after integer NOT NULL, + description text, + meta jsonb DEFAULT '{}'::jsonb, + created_at timestamp with time zone DEFAULT now() NOT NULL +); + + +-- +-- Name: user_transactions_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.user_transactions_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: user_transactions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.user_transactions_id_seq OWNED BY public.user_transactions.id; + + +-- +-- Name: users; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.users ( + id integer NOT NULL, + email character varying(255) NOT NULL, + password text NOT NULL, + name character varying(255), + plan character varying(20) DEFAULT 'free'::character varying, + api_key character varying(64), + tokens_used bigint DEFAULT 0, + created_at timestamp with time zone DEFAULT now(), + is_admin boolean DEFAULT false NOT NULL, + is_blocked boolean DEFAULT false +); + + +-- +-- Name: COLUMN users.is_admin; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.users.is_admin IS 'Админ tool (доступ ΠΊ /system ΠΈ Ρ‚.ΠΏ.)'; + + +-- +-- Name: users_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.users_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: users_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.users_id_seq OWNED BY public.users.id; + + +-- +-- Name: ai_usage id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.ai_usage ALTER COLUMN id SET DEFAULT nextval('public.ai_usage_id_seq'::regclass); + + +-- +-- Name: articles id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.articles ALTER COLUMN id SET DEFAULT nextval('public.articles_id_seq'::regclass); + + +-- +-- Name: autogen_settings id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.autogen_settings ALTER COLUMN id SET DEFAULT nextval('public.autogen_settings_id_seq'::regclass); + + +-- +-- Name: blog_topics id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.blog_topics ALTER COLUMN id SET DEFAULT nextval('public.blog_topics_id_seq'::regclass); + + +-- +-- Name: categories id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.categories ALTER COLUMN id SET DEFAULT nextval('public.categories_id_seq'::regclass); + + +-- +-- Name: channel_stats id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.channel_stats ALTER COLUMN id SET DEFAULT nextval('public.channel_stats_id_seq'::regclass); + + +-- +-- Name: channel_topics id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.channel_topics ALTER COLUMN id SET DEFAULT nextval('public.channel_topics_id_seq'::regclass); + + +-- +-- Name: channels id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.channels ALTER COLUMN id SET DEFAULT nextval('public.channels_id_seq'::regclass); + + +-- +-- Name: content_queue id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.content_queue ALTER COLUMN id SET DEFAULT nextval('public.content_queue_id_seq'::regclass); + + +-- +-- Name: editor_notes id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.editor_notes ALTER COLUMN id SET DEFAULT nextval('public.editor_notes_id_seq'::regclass); + + +-- +-- Name: generation_jobs id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.generation_jobs ALTER COLUMN id SET DEFAULT nextval('public.generation_jobs_id_seq'::regclass); + + +-- +-- Name: inbox_messages id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.inbox_messages ALTER COLUMN id SET DEFAULT nextval('public.inbox_messages_id_seq'::regclass); + + +-- +-- Name: payment_orders id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.payment_orders ALTER COLUMN id SET DEFAULT nextval('public.payment_orders_id_seq'::regclass); + + +-- +-- Name: photo_search_profiles id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.photo_search_profiles ALTER COLUMN id SET DEFAULT nextval('public.photo_search_profiles_id_seq'::regclass); + + +-- +-- Name: plans id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.plans ALTER COLUMN id SET DEFAULT nextval('public.plans_id_seq'::regclass); + + +-- +-- Name: post_drafts id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.post_drafts ALTER COLUMN id SET DEFAULT nextval('public.post_drafts_id_seq'::regclass); + + +-- +-- Name: post_metrics id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.post_metrics ALTER COLUMN id SET DEFAULT nextval('public.post_metrics_id_seq'::regclass); + + +-- +-- Name: posts id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.posts ALTER COLUMN id SET DEFAULT nextval('public.posts_id_seq'::regclass); + + +-- +-- Name: promo_codes id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.promo_codes ALTER COLUMN id SET DEFAULT nextval('public.promo_codes_id_seq'::regclass); + + +-- +-- Name: promo_usages id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.promo_usages ALTER COLUMN id SET DEFAULT nextval('public.promo_usages_id_seq'::regclass); + + +-- +-- Name: publish_slots id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.publish_slots ALTER COLUMN id SET DEFAULT nextval('public.publish_slots_id_seq'::regclass); + + +-- +-- Name: scheduled_posts id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.scheduled_posts ALTER COLUMN id SET DEFAULT nextval('public.scheduled_posts_id_seq'::regclass); + + +-- +-- Name: series id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.series ALTER COLUMN id SET DEFAULT nextval('public.series_id_seq'::regclass); + + +-- +-- Name: user_posts id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.user_posts ALTER COLUMN id SET DEFAULT nextval('public.user_posts_id_seq'::regclass); + + +-- +-- Name: user_subscriptions id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.user_subscriptions ALTER COLUMN id SET DEFAULT nextval('public.user_subscriptions_id_seq'::regclass); + + +-- +-- Name: user_transactions id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.user_transactions ALTER COLUMN id SET DEFAULT nextval('public.user_transactions_id_seq'::regclass); + + +-- +-- Name: users id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.users ALTER COLUMN id SET DEFAULT nextval('public.users_id_seq'::regclass); + + +-- +-- Name: ai_usage ai_usage_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.ai_usage + ADD CONSTRAINT ai_usage_pkey PRIMARY KEY (id); + + +-- +-- Name: app_settings app_settings_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.app_settings + ADD CONSTRAINT app_settings_pkey PRIMARY KEY (key); + + +-- +-- Name: articles articles_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.articles + ADD CONSTRAINT articles_pkey PRIMARY KEY (id); + + +-- +-- Name: articles articles_slug_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.articles + ADD CONSTRAINT articles_slug_key UNIQUE (slug); + + +-- +-- Name: autogen_settings autogen_settings_category_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.autogen_settings + ADD CONSTRAINT autogen_settings_category_key UNIQUE (category); + + +-- +-- Name: autogen_settings autogen_settings_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.autogen_settings + ADD CONSTRAINT autogen_settings_pkey PRIMARY KEY (id); + + +-- +-- Name: blog_topics blog_topics_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.blog_topics + ADD CONSTRAINT blog_topics_pkey PRIMARY KEY (id); + + +-- +-- Name: categories categories_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.categories + ADD CONSTRAINT categories_pkey PRIMARY KEY (id); + + +-- +-- Name: categories categories_slug_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.categories + ADD CONSTRAINT categories_slug_key UNIQUE (slug); + + +-- +-- Name: channel_schedule channel_schedule_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.channel_schedule + ADD CONSTRAINT channel_schedule_pkey PRIMARY KEY (channel_id); + + +-- +-- Name: channel_stats channel_stats_channel_id_captured_at_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.channel_stats + ADD CONSTRAINT channel_stats_channel_id_captured_at_key UNIQUE (channel_id, captured_at); + + +-- +-- Name: channel_stats channel_stats_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.channel_stats + ADD CONSTRAINT channel_stats_pkey PRIMARY KEY (id); + + +-- +-- Name: channel_style channel_style_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.channel_style + ADD CONSTRAINT channel_style_pkey PRIMARY KEY (channel_id); + + +-- +-- Name: channel_topics channel_topics_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.channel_topics + ADD CONSTRAINT channel_topics_pkey PRIMARY KEY (id); + + +-- +-- Name: channels channels_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.channels + ADD CONSTRAINT channels_pkey PRIMARY KEY (id); + + +-- +-- Name: content_queue content_queue_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.content_queue + ADD CONSTRAINT content_queue_pkey PRIMARY KEY (id); + + +-- +-- Name: credit_costs credit_costs_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.credit_costs + ADD CONSTRAINT credit_costs_pkey PRIMARY KEY (operation); + + +-- +-- Name: editor_notes editor_notes_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.editor_notes + ADD CONSTRAINT editor_notes_pkey PRIMARY KEY (id); + + +-- +-- Name: generation_jobs generation_jobs_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.generation_jobs + ADD CONSTRAINT generation_jobs_pkey PRIMARY KEY (id); + + +-- +-- Name: inbox_messages inbox_messages_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.inbox_messages + ADD CONSTRAINT inbox_messages_pkey PRIMARY KEY (id); + + +-- +-- Name: payment_orders payment_orders_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.payment_orders + ADD CONSTRAINT payment_orders_pkey PRIMARY KEY (id); + + +-- +-- Name: payment_orders payment_orders_yukassa_payment_id_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.payment_orders + ADD CONSTRAINT payment_orders_yukassa_payment_id_key UNIQUE (yukassa_payment_id); + + +-- +-- Name: photo_search_profiles photo_search_profiles_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.photo_search_profiles + ADD CONSTRAINT photo_search_profiles_pkey PRIMARY KEY (id); + + +-- +-- Name: photo_search_profiles photo_search_profiles_slug_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.photo_search_profiles + ADD CONSTRAINT photo_search_profiles_slug_key UNIQUE (slug); + + +-- +-- Name: plans plans_code_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.plans + ADD CONSTRAINT plans_code_key UNIQUE (code); + + +-- +-- Name: plans plans_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.plans + ADD CONSTRAINT plans_pkey PRIMARY KEY (id); + + +-- +-- Name: post_drafts post_drafts_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.post_drafts + ADD CONSTRAINT post_drafts_pkey PRIMARY KEY (id); + + +-- +-- Name: post_metrics post_metrics_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.post_metrics + ADD CONSTRAINT post_metrics_pkey PRIMARY KEY (id); + + +-- +-- Name: posts posts_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.posts + ADD CONSTRAINT posts_pkey PRIMARY KEY (id); + + +-- +-- Name: promo_codes promo_codes_code_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.promo_codes + ADD CONSTRAINT promo_codes_code_key UNIQUE (code); + + +-- +-- Name: promo_codes promo_codes_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.promo_codes + ADD CONSTRAINT promo_codes_pkey PRIMARY KEY (id); + + +-- +-- Name: promo_usages promo_usages_code_id_user_id_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.promo_usages + ADD CONSTRAINT promo_usages_code_id_user_id_key UNIQUE (code_id, user_id); + + +-- +-- Name: promo_usages promo_usages_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.promo_usages + ADD CONSTRAINT promo_usages_pkey PRIMARY KEY (id); + + +-- +-- Name: publish_slots publish_slots_channel_id_slot_hour_slot_minute_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.publish_slots + ADD CONSTRAINT publish_slots_channel_id_slot_hour_slot_minute_key UNIQUE (channel_id, slot_hour, slot_minute); + + +-- +-- Name: publish_slots publish_slots_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.publish_slots + ADD CONSTRAINT publish_slots_pkey PRIMARY KEY (id); + + +-- +-- Name: scheduled_posts scheduled_posts_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.scheduled_posts + ADD CONSTRAINT scheduled_posts_pkey PRIMARY KEY (id); + + +-- +-- Name: series series_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.series + ADD CONSTRAINT series_pkey PRIMARY KEY (id); + + +-- +-- Name: series series_slug_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.series + ADD CONSTRAINT series_slug_key UNIQUE (slug); + + +-- +-- Name: user_balance user_balance_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.user_balance + ADD CONSTRAINT user_balance_pkey PRIMARY KEY (user_id); + + +-- +-- Name: user_posts user_posts_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.user_posts + ADD CONSTRAINT user_posts_pkey PRIMARY KEY (id); + + +-- +-- Name: user_subscriptions user_subscriptions_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.user_subscriptions + ADD CONSTRAINT user_subscriptions_pkey PRIMARY KEY (id); + + +-- +-- Name: user_transactions user_transactions_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.user_transactions + ADD CONSTRAINT user_transactions_pkey PRIMARY KEY (id); + + +-- +-- Name: users users_api_key_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.users + ADD CONSTRAINT users_api_key_key UNIQUE (api_key); + + +-- +-- Name: users users_email_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.users + ADD CONSTRAINT users_email_key UNIQUE (email); + + +-- +-- Name: users users_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.users + ADD CONSTRAINT users_pkey PRIMARY KEY (id); + + +-- +-- Name: ai_usage_created_at_idx; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX ai_usage_created_at_idx ON public.ai_usage USING btree (created_at DESC); + + +-- +-- Name: ai_usage_provider_model_idx; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX ai_usage_provider_model_idx ON public.ai_usage USING btree (provider, model); + + +-- +-- Name: ai_usage_service_idx; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX ai_usage_service_idx ON public.ai_usage USING btree (service, created_at DESC); + + +-- +-- Name: idx_articles_slug; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_articles_slug ON public.articles USING btree (slug); + + +-- +-- Name: idx_articles_status_pub; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_articles_status_pub ON public.articles USING btree (status, published_at DESC); + + +-- +-- Name: idx_articles_title_lower; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_articles_title_lower ON public.articles USING btree (lower((title)::text) text_pattern_ops); + + +-- +-- Name: idx_articles_topic_hash; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_articles_topic_hash ON public.articles USING btree (topic_hash) WHERE (topic_hash IS NOT NULL); + + +-- +-- Name: idx_blog_topics_category; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_blog_topics_category ON public.blog_topics USING btree (category, is_used); + + +-- +-- Name: idx_blog_topics_unique; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX idx_blog_topics_unique ON public.blog_topics USING btree (category, topic); + + +-- +-- Name: idx_channel_stats_channel_time; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_channel_stats_channel_time ON public.channel_stats USING btree (channel_id, captured_at DESC); + + +-- +-- Name: idx_channel_topics_channel; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_channel_topics_channel ON public.channel_topics USING btree (channel_id, is_used, created_at); + + +-- +-- Name: idx_channels_user; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_channels_user ON public.channels USING btree (user_id); + + +-- +-- Name: idx_inbox_channel; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_inbox_channel ON public.inbox_messages USING btree (channel_id, created_at DESC); + + +-- +-- Name: idx_inbox_ext; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX idx_inbox_ext ON public.inbox_messages USING btree (channel_id, external_msg_id) WHERE (external_msg_id IS NOT NULL); + + +-- +-- Name: idx_inbox_status; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_inbox_status ON public.inbox_messages USING btree (channel_id, status); + + +-- +-- Name: idx_jobs_status; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_jobs_status ON public.generation_jobs USING btree (status); + + +-- +-- Name: idx_jobs_user; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_jobs_user ON public.generation_jobs USING btree (user_id); + + +-- +-- Name: idx_notes_pub; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_notes_pub ON public.editor_notes USING btree (is_published, created_at DESC); + + +-- +-- Name: idx_payment_orders_user; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_payment_orders_user ON public.payment_orders USING btree (user_id, created_at DESC); + + +-- +-- Name: idx_post_drafts_channel; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_post_drafts_channel ON public.post_drafts USING btree (channel_id, status, created_at DESC); + + +-- +-- Name: idx_post_drafts_user; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_post_drafts_user ON public.post_drafts USING btree (user_id, status); + + +-- +-- Name: idx_post_metrics_post; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_post_metrics_post ON public.post_metrics USING btree (post_id, captured_at DESC); + + +-- +-- Name: idx_post_metrics_userpost; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_post_metrics_userpost ON public.post_metrics USING btree (user_post_id, captured_at DESC); + + +-- +-- Name: idx_posts_channel; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_posts_channel ON public.posts USING btree (channel_id); + + +-- +-- Name: idx_posts_scheduled; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_posts_scheduled ON public.posts USING btree (scheduled_at) WHERE ((status)::text = 'scheduled'::text); + + +-- +-- Name: idx_scheduled_posts_channel_article; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_scheduled_posts_channel_article ON public.scheduled_posts USING btree (channel_id, article_id); + + +-- +-- Name: idx_scheduled_posts_status_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_scheduled_posts_status_at ON public.scheduled_posts USING btree (status, scheduled_at); + + +-- +-- Name: idx_series_slug; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_series_slug ON public.series USING btree (slug); + + +-- +-- Name: idx_user_posts_channel; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_user_posts_channel ON public.user_posts USING btree (channel_id, created_at DESC); + + +-- +-- Name: idx_user_transactions_user_id; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX idx_user_transactions_user_id ON public.user_transactions USING btree (user_id, created_at DESC); + + +-- +-- Name: articles articles_job_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.articles + ADD CONSTRAINT articles_job_id_fkey FOREIGN KEY (job_id) REFERENCES public.generation_jobs(id) ON DELETE SET NULL; + + +-- +-- Name: channel_schedule channel_schedule_channel_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.channel_schedule + ADD CONSTRAINT channel_schedule_channel_id_fkey FOREIGN KEY (channel_id) REFERENCES public.channels(id) ON DELETE CASCADE; + + +-- +-- Name: channel_stats channel_stats_channel_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.channel_stats + ADD CONSTRAINT channel_stats_channel_id_fkey FOREIGN KEY (channel_id) REFERENCES public.channels(id) ON DELETE CASCADE; + + +-- +-- Name: channel_style channel_style_channel_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.channel_style + ADD CONSTRAINT channel_style_channel_id_fkey FOREIGN KEY (channel_id) REFERENCES public.channels(id) ON DELETE CASCADE; + + +-- +-- Name: channel_topics channel_topics_channel_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.channel_topics + ADD CONSTRAINT channel_topics_channel_id_fkey FOREIGN KEY (channel_id) REFERENCES public.channels(id) ON DELETE CASCADE; + + +-- +-- Name: channels channels_photo_search_profile_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.channels + ADD CONSTRAINT channels_photo_search_profile_id_fkey FOREIGN KEY (photo_search_profile_id) REFERENCES public.photo_search_profiles(id) ON DELETE SET NULL; + + +-- +-- Name: channels channels_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.channels + ADD CONSTRAINT channels_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE; + + +-- +-- Name: content_queue content_queue_article_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.content_queue + ADD CONSTRAINT content_queue_article_id_fkey FOREIGN KEY (article_id) REFERENCES public.articles(id) ON DELETE SET NULL; + + +-- +-- Name: generation_jobs generation_jobs_channel_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.generation_jobs + ADD CONSTRAINT generation_jobs_channel_id_fkey FOREIGN KEY (channel_id) REFERENCES public.channels(id) ON DELETE SET NULL; + + +-- +-- Name: generation_jobs generation_jobs_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.generation_jobs + ADD CONSTRAINT generation_jobs_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE SET NULL; + + +-- +-- Name: inbox_messages inbox_messages_channel_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.inbox_messages + ADD CONSTRAINT inbox_messages_channel_id_fkey FOREIGN KEY (channel_id) REFERENCES public.channels(id) ON DELETE CASCADE; + + +-- +-- Name: payment_orders payment_orders_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.payment_orders + ADD CONSTRAINT payment_orders_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE; + + +-- +-- Name: post_drafts post_drafts_channel_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.post_drafts + ADD CONSTRAINT post_drafts_channel_id_fkey FOREIGN KEY (channel_id) REFERENCES public.channels(id) ON DELETE CASCADE; + + +-- +-- Name: post_drafts post_drafts_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.post_drafts + ADD CONSTRAINT post_drafts_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE SET NULL; + + +-- +-- Name: post_metrics post_metrics_post_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.post_metrics + ADD CONSTRAINT post_metrics_post_id_fkey FOREIGN KEY (post_id) REFERENCES public.posts(id) ON DELETE CASCADE; + + +-- +-- Name: post_metrics post_metrics_user_post_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.post_metrics + ADD CONSTRAINT post_metrics_user_post_id_fkey FOREIGN KEY (user_post_id) REFERENCES public.user_posts(id) ON DELETE CASCADE; + + +-- +-- Name: posts posts_channel_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.posts + ADD CONSTRAINT posts_channel_id_fkey FOREIGN KEY (channel_id) REFERENCES public.channels(id) ON DELETE CASCADE; + + +-- +-- Name: posts posts_job_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.posts + ADD CONSTRAINT posts_job_id_fkey FOREIGN KEY (job_id) REFERENCES public.generation_jobs(id) ON DELETE SET NULL; + + +-- +-- Name: promo_usages promo_usages_code_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.promo_usages + ADD CONSTRAINT promo_usages_code_id_fkey FOREIGN KEY (code_id) REFERENCES public.promo_codes(id); + + +-- +-- Name: promo_usages promo_usages_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.promo_usages + ADD CONSTRAINT promo_usages_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id); + + +-- +-- Name: publish_slots publish_slots_channel_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.publish_slots + ADD CONSTRAINT publish_slots_channel_id_fkey FOREIGN KEY (channel_id) REFERENCES public.channels(id) ON DELETE CASCADE; + + +-- +-- Name: scheduled_posts scheduled_posts_article_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.scheduled_posts + ADD CONSTRAINT scheduled_posts_article_id_fkey FOREIGN KEY (article_id) REFERENCES public.articles(id) ON DELETE SET NULL; + + +-- +-- Name: scheduled_posts scheduled_posts_channel_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.scheduled_posts + ADD CONSTRAINT scheduled_posts_channel_id_fkey FOREIGN KEY (channel_id) REFERENCES public.channels(id) ON DELETE CASCADE; + + +-- +-- Name: user_balance user_balance_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.user_balance + ADD CONSTRAINT user_balance_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE; + + +-- +-- Name: user_posts user_posts_channel_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.user_posts + ADD CONSTRAINT user_posts_channel_id_fkey FOREIGN KEY (channel_id) REFERENCES public.channels(id) ON DELETE CASCADE; + + +-- +-- Name: user_subscriptions user_subscriptions_plan_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.user_subscriptions + ADD CONSTRAINT user_subscriptions_plan_id_fkey FOREIGN KEY (plan_id) REFERENCES public.plans(id); + + +-- +-- Name: user_subscriptions user_subscriptions_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.user_subscriptions + ADD CONSTRAINT user_subscriptions_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE; + + +-- +-- Name: user_transactions user_transactions_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.user_transactions + ADD CONSTRAINT user_transactions_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE; + + +-- +-- PostgreSQL database dump complete +-- + +\unrestrict VhNY3y2jfbhtHWUJNX17PN7SRgHPDQoK22OdEvgq8EbNJ3oFJFZi6W1o1ShNkWQ +