diff --git a/drizzle/0000_baseline_prod_2026_05_19.sql b/drizzle/0000_baseline_prod_2026_05_19.sql new file mode 100644 index 0000000..a36fb60 --- /dev/null +++ b/drizzle/0000_baseline_prod_2026_05_19.sql @@ -0,0 +1,430 @@ +CREATE TYPE "public"."child_sex" AS ENUM('male', 'female', 'other');--> statement-breakpoint +CREATE TYPE "public"."child_stage" AS ENUM('newborn', 'infant', 'solids_start', 'toddler_early', 'toddler_late', 'preschool');--> statement-breakpoint +CREATE TYPE "public"."member_role" AS ENUM('admin', 'caregiver', 'viewer');--> statement-breakpoint +CREATE TYPE "public"."diaper_type" AS ENUM('wet', 'dirty', 'both', 'dry');--> statement-breakpoint +CREATE TYPE "public"."feed_method" AS ENUM('bottle', 'breast_left', 'breast_right', 'breast_both', 'cup', 'spoon', 'finger', 'self');--> statement-breakpoint +CREATE TYPE "public"."feed_type" AS ENUM('breast_milk', 'formula', 'solid', 'water', 'other');--> statement-breakpoint +CREATE TYPE "public"."sleep_type" AS ENUM('nap', 'night');--> statement-breakpoint +CREATE TABLE "admin_sessions" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "admin_id" uuid NOT NULL, + "session_token" text NOT NULL, + "expires" timestamp with time zone NOT NULL, + "created_at" timestamp with time zone DEFAULT now(), + CONSTRAINT "admin_sessions_session_token_unique" UNIQUE("session_token") +); +--> statement-breakpoint +CREATE TABLE "admins" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "username" varchar(50) NOT NULL, + "password_hash" varchar(255) NOT NULL, + "role" varchar(20) DEFAULT 'admin', + "created_at" timestamp with time zone DEFAULT now(), + "last_login" timestamp with time zone, + CONSTRAINT "admins_username_unique" UNIQUE("username"), + CONSTRAINT "admins_role_check" CHECK ((role)::text = ANY (ARRAY['super_admin','admin','support'])) +); +--> statement-breakpoint +CREATE TABLE "password_resets" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "user_id" uuid NOT NULL, + "token" text NOT NULL, + "expires_at" timestamp with time zone NOT NULL, + "used_at" timestamp with time zone, + CONSTRAINT "password_resets_token_unique" UNIQUE("token") +); +--> statement-breakpoint +CREATE TABLE "member_profiles" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "user_id" uuid NOT NULL, + "family_id" uuid NOT NULL, + "slug" text NOT NULL, + "display_name" text NOT NULL, + "bio" text, + "avatar_url" text, + "is_public" boolean DEFAULT false NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "member_profiles_user_id_unique" UNIQUE("user_id") +); +--> statement-breakpoint +CREATE TABLE "product_clicks" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "product_id" uuid NOT NULL, + "clicked_at" timestamp with time zone DEFAULT now() NOT NULL, + "referrer" text, + "ip_hash" text +); +--> statement-breakpoint +CREATE TABLE "recommended_products" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "profile_id" uuid NOT NULL, + "title" text NOT NULL, + "description" text, + "url" text NOT NULL, + "image_url" text, + "category" text DEFAULT 'general' NOT NULL, + "display_order" integer DEFAULT 0 NOT NULL, + "is_active" boolean DEFAULT true NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "ai_usage" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "family_id" uuid, + "user_id" uuid, + "intent" text, + "model_used" text, + "prompt_tokens" integer, + "completion_tokens" integer, + "total_tokens" integer, + "cost_estimate_paise" numeric(10, 4), + "duration_ms" integer, + "created_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "chat_messages" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "session_id" uuid NOT NULL, + "role" varchar(20) NOT NULL, + "content" text NOT NULL, + "created_at" timestamp with time zone DEFAULT now() +); +--> statement-breakpoint +CREATE TABLE "chat_sessions" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "child_id" uuid NOT NULL, + "title" varchar(255) DEFAULT 'New conversation' NOT NULL, + "created_at" timestamp with time zone DEFAULT now(), + "updated_at" timestamp with time zone DEFAULT now() +); +--> statement-breakpoint +CREATE TABLE "audit_log" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "family_id" uuid, + "user_id" uuid, + "action" varchar(50) NOT NULL, + "resource_type" varchar(50), + "resource_id" uuid, + "ip_address" varchar(45), + "user_agent" text, + "metadata" jsonb DEFAULT '{}'::jsonb, + "created_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "log_corrections" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "family_id" uuid NOT NULL, + "dose_id" uuid NOT NULL, + "original_value" jsonb NOT NULL, + "corrected_value" jsonb NOT NULL, + "reason" text, + "corrected_by" uuid, + "created_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "accounts" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "user_id" uuid NOT NULL, + "type" text NOT NULL, + "provider" text NOT NULL, + "provider_account_id" text NOT NULL, + "refresh_token" text, + "access_token" text, + "expires_at" timestamp, + "token_type" text, + "scope" text, + "id_token" text, + "session_state" text +); +--> statement-breakpoint +CREATE TABLE "sessions" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "session_token" text NOT NULL, + "user_id" uuid NOT NULL, + "expires" timestamp NOT NULL, + CONSTRAINT "sessions_session_token_unique" UNIQUE("session_token") +); +--> statement-breakpoint +CREATE TABLE "users" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "name" text, + "email" text NOT NULL, + "email_verified" timestamp, + "image" text, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL, + "password_hash" varchar(255), + "password_updated_at" timestamp with time zone, + CONSTRAINT "users_email_unique" UNIQUE("email") +); +--> statement-breakpoint +CREATE TABLE "verification_tokens" ( + "identifier" text NOT NULL, + "token" text NOT NULL, + "expires" timestamp NOT NULL +); +--> statement-breakpoint +CREATE TABLE "children" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "family_id" uuid NOT NULL, + "name" text NOT NULL, + "birth_date" date NOT NULL, + "sex" "child_sex", + "stage" "child_stage" DEFAULT 'newborn' NOT NULL, + "image_url" text, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "families" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "name" text NOT NULL, + "tier" varchar(20) DEFAULT 'free', + "max_children" integer DEFAULT 1, + "max_members" integer DEFAULT 2, + "pediatrician_phone" text, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "family_invites" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "family_id" uuid NOT NULL, + "email" text NOT NULL, + "role" "member_role" DEFAULT 'viewer' NOT NULL, + "token" text NOT NULL, + "expires_at" timestamp NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + CONSTRAINT "family_invites_token_unique" UNIQUE("token") +); +--> statement-breakpoint +CREATE TABLE "family_members" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "family_id" uuid NOT NULL, + "user_id" uuid NOT NULL, + "role" "member_role" DEFAULT 'caregiver' NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "attachments" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "family_id" uuid NOT NULL, + "log_entry_id" uuid, + "r2_key" text NOT NULL, + "r2_thumbnail_key" text, + "mime_type" text, + "size_bytes" integer, + "uploaded_by" uuid, + "created_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "memories" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "family_id" uuid NOT NULL, + "child_id" uuid, + "title" text, + "description" text, + "taken_at" timestamp with time zone, + "r2_key" text NOT NULL, + "r2_thumbnail_key" text, + "mime_type" text, + "size_bytes" integer, + "width" integer, + "height" integer, + "vision_caption" text, + "vision_tags" text[], + "vision_embedding" vector(1536), + "is_private" boolean DEFAULT false NOT NULL, + "processing_status" text DEFAULT 'uploading' NOT NULL, + "uploaded_by" uuid, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "diapers_logs" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "child_id" uuid NOT NULL, + "type" "diaper_type" NOT NULL, + "notes" text, + "logged_at" timestamp DEFAULT now() NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "feeds" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "child_id" uuid NOT NULL, + "type" "feed_type" NOT NULL, + "method" "feed_method", + "amount_ml" real, + "notes" text, + "logged_at" timestamp DEFAULT now() NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "growth" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "child_id" uuid NOT NULL, + "measured_at" timestamp NOT NULL, + "weight_kg" real, + "height_cm" real, + "head_circumference_cm" real, + "notes" text, + "created_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "medications" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "child_id" uuid NOT NULL, + "name" text NOT NULL, + "dosage" text, + "frequency" text, + "start_date" date NOT NULL, + "end_date" date, + "active" boolean DEFAULT true NOT NULL, + "notes" text, + "created_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "milestone_achievements" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "child_id" uuid NOT NULL, + "family_id" uuid NOT NULL, + "milestone_key" text NOT NULL, + "achieved_at" date NOT NULL, + "notes" text, + "created_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "sleeps" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "child_id" uuid NOT NULL, + "type" "sleep_type" NOT NULL, + "started_at" timestamp, + "ended_at" timestamp, + "duration_minutes" integer, + "notes" text, + "logged_at" timestamp DEFAULT now() NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "vaccinations" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "child_id" uuid NOT NULL, + "vaccine_name" text NOT NULL, + "scheduled_date" date NOT NULL, + "given_date" date, + "status" text DEFAULT 'pending' NOT NULL, + "provider" text, + "lot_number" text, + "notes" text, + "created_at" timestamp DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "allergies" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "child_id" uuid NOT NULL, + "name" varchar(255) NOT NULL, + "severity" varchar(50) DEFAULT 'mild', + "notes" text, + "created_at" timestamp with time zone DEFAULT now(), + "updated_at" timestamp with time zone DEFAULT now() +); +--> statement-breakpoint +CREATE TABLE "doctor_visits" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "child_id" uuid NOT NULL, + "doctor_name" varchar(255) NOT NULL, + "reason" varchar(255), + "visit_date" date NOT NULL, + "notes" text, + "created_at" timestamp with time zone DEFAULT now(), + "updated_at" timestamp with time zone DEFAULT now() +); +--> statement-breakpoint +CREATE TABLE "illness_logs" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "child_id" uuid NOT NULL, + "name" varchar(255) NOT NULL, + "start_date" date NOT NULL, + "end_date" date, + "notes" text, + "created_at" timestamp with time zone DEFAULT now(), + "updated_at" timestamp with time zone DEFAULT now() +); +--> statement-breakpoint +CREATE TABLE "medication_doses" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "medicine_id" uuid NOT NULL, + "family_id" uuid NOT NULL, + "administered_at" timestamp with time zone DEFAULT now() NOT NULL, + "administered_by" uuid, + "amount_given" text, + "notes" text, + "created_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "medicines" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "child_id" uuid NOT NULL, + "name" varchar(255) NOT NULL, + "dose" varchar(255), + "notes" text, + "reminder_time" varchar(10), + "created_at" timestamp with time zone DEFAULT now(), + "updated_at" timestamp with time zone DEFAULT now() +); +--> statement-breakpoint +CREATE TABLE "support_responses" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "ticket_id" uuid, + "admin_id" uuid, + "message" text NOT NULL, + "created_at" timestamp with time zone DEFAULT now() +); +--> statement-breakpoint +CREATE TABLE "support_tickets" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "family_id" uuid, + "user_id" uuid, + "email" varchar(255) NOT NULL, + "subject" varchar(255) NOT NULL, + "description" text, + "status" varchar(20) DEFAULT 'open', + "priority" varchar(20) DEFAULT 'normal', + "created_at" timestamp with time zone DEFAULT now(), + "updated_at" timestamp with time zone DEFAULT now(), + CONSTRAINT "support_tickets_status_check" CHECK ((status)::text = ANY (ARRAY['open','in_progress','resolved','closed'])), + CONSTRAINT "support_tickets_priority_check" CHECK ((priority)::text = ANY (ARRAY['low','normal','high','urgent'])) +); +--> statement-breakpoint +ALTER TABLE "diapers_logs" ADD CONSTRAINT "diapers_logs_child_id_children_id_fk" FOREIGN KEY ("child_id") REFERENCES "public"."children"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "feeds" ADD CONSTRAINT "feeds_child_id_children_id_fk" FOREIGN KEY ("child_id") REFERENCES "public"."children"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "growth" ADD CONSTRAINT "growth_child_id_children_id_fk" FOREIGN KEY ("child_id") REFERENCES "public"."children"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "medications" ADD CONSTRAINT "medications_child_id_children_id_fk" FOREIGN KEY ("child_id") REFERENCES "public"."children"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "sleeps" ADD CONSTRAINT "sleeps_child_id_children_id_fk" FOREIGN KEY ("child_id") REFERENCES "public"."children"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "vaccinations" ADD CONSTRAINT "vaccinations_child_id_children_id_fk" FOREIGN KEY ("child_id") REFERENCES "public"."children"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +CREATE INDEX "member_profiles_slug_idx" ON "member_profiles" USING btree ("slug");--> statement-breakpoint +CREATE INDEX "product_clicks_product_idx" ON "product_clicks" USING btree ("product_id","clicked_at");--> statement-breakpoint +CREATE INDEX "recommended_products_profile_idx" ON "recommended_products" USING btree ("profile_id","display_order");--> statement-breakpoint +CREATE INDEX "ai_usage_created_idx" ON "ai_usage" USING btree ("created_at");--> statement-breakpoint +CREATE INDEX "ai_usage_family_idx" ON "ai_usage" USING btree ("family_id");--> statement-breakpoint +CREATE INDEX "audit_family_idx" ON "audit_log" USING btree ("family_id","created_at");--> statement-breakpoint +CREATE INDEX "idx_audit_log_action" ON "audit_log" USING btree ("action");--> statement-breakpoint +CREATE INDEX "idx_audit_log_created" ON "audit_log" USING btree ("created_at");--> statement-breakpoint +CREATE INDEX "idx_audit_log_family" ON "audit_log" USING btree ("family_id");--> statement-breakpoint +CREATE INDEX "idx_audit_log_user" ON "audit_log" USING btree ("user_id");--> statement-breakpoint +CREATE INDEX "log_corrections_dose_idx" ON "log_corrections" USING btree ("dose_id");--> statement-breakpoint +CREATE UNIQUE INDEX "accounts_provider_idx" ON "accounts" USING btree ("provider","provider_account_id");--> statement-breakpoint +CREATE UNIQUE INDEX "verification_tokens_idx" ON "verification_tokens" USING btree ("identifier","token");--> statement-breakpoint +CREATE INDEX "children_family_idx" ON "children" USING btree ("family_id");--> statement-breakpoint +CREATE UNIQUE INDEX "invite_token_idx" ON "family_invites" USING btree ("token");--> statement-breakpoint +CREATE UNIQUE INDEX "family_members_family_id_user_id_key" ON "family_members" USING btree ("family_id","user_id");--> statement-breakpoint +CREATE INDEX "attachments_family_idx" ON "attachments" USING btree ("family_id");--> statement-breakpoint +CREATE INDEX "memories_family_idx" ON "memories" USING btree ("family_id");--> statement-breakpoint +CREATE INDEX "memories_child_idx" ON "memories" USING btree ("child_id");--> statement-breakpoint +CREATE INDEX "memories_embedding_idx" ON "memories" USING ivfflat ("vision_embedding" vector_cosine_ops) WITH (lists=100);--> statement-breakpoint +CREATE INDEX "milestone_child_idx" ON "milestone_achievements" USING btree ("child_id");--> statement-breakpoint +CREATE UNIQUE INDEX "milestone_achievements_child_milestone_unique" ON "milestone_achievements" USING btree ("child_id","milestone_key");--> statement-breakpoint +CREATE INDEX "medication_doses_family_idx" ON "medication_doses" USING btree ("family_id");--> statement-breakpoint +CREATE INDEX "medication_doses_medicine_idx" ON "medication_doses" USING btree ("medicine_id"); \ No newline at end of file diff --git a/drizzle/README.md b/drizzle/README.md new file mode 100644 index 0000000..0f28078 --- /dev/null +++ b/drizzle/README.md @@ -0,0 +1,55 @@ +# Tia — Database Migrations + +This folder is **source code** and is committed to git. It is consumed by the +deploy pipeline (`pnpm db:migrate`, run on container start — see `Dockerfile`). + +## Baseline reset — 2026-05-19 + +The project's first 16 migrations (`0000`–`0015`) plus a `manual/` folder were +hand-rolled SQL applied directly via the Dokploy database terminal. They were +**never** run through Drizzle's migrator, so: + +- prod had no `__drizzle_migrations` tracking table; +- the `drizzle/` folder was gitignored, so migration SQL never reached the server; +- `schema.ts` had drifted well behind the real production schema. + +To fix this we performed a **Path A baseline reset**: + +1. `pg_dump` backup of prod taken and stored off-server. +2. `drizzle-kit pull` introspected the live prod schema (35 tables). +3. `src/db/schema/*.ts` was rewritten to match prod exactly. +4. Legacy migrations were archived to `_archived_pre_baseline_2026-05-19/` + (also retained in git history). +5. A single fresh baseline — `0000_baseline_prod_2026_05_19.sql` — was generated + and **verified column-for-column against the introspected prod schema**. +6. Prod's `drizzle.__drizzle_migrations` table was created and seeded with one + row marking `0000_baseline_prod_2026_05_19` as already applied, so the + migrator treats prod as up-to-date and runs nothing on the next deploy. + +## Normal workflow from here + +```bash +# 1. Edit src/db/schema/*.ts +# 2. Generate a migration from the diff: +pnpm db:generate # writes drizzle/000N_.sql +# 3. Review the generated SQL by eye. +# 4. Apply locally against the dev DB: +pnpm db:migrate +# 5. Commit schema + migration together, then push. +# Dokploy redeploys; the migrator applies it in prod on container start. +``` + +## Hard rules + +- **Never** edit a migration file after it has been pushed. Fix-forward with a + new migration instead. +- **Never** run schema-changing SQL directly against prod. It becomes drift. +- The `drizzle/` folder must stay **out** of `.gitignore`. + +## RLS policies + +Five log tables (`feeds`, `diapers_logs`, `sleeps`, `vaccinations`, `growth`) +plus `children` / `family_members` carry row-level-security policies in prod. +These are **not** modelled in the `pgTable` definitions and are managed +separately in the database. Drizzle migrations will not recreate them — keep +that in mind if you ever rebuild the DB from scratch. diff --git a/drizzle/meta/0000_snapshot.json b/drizzle/meta/0000_snapshot.json new file mode 100644 index 0000000..2ff3f82 --- /dev/null +++ b/drizzle/meta/0000_snapshot.json @@ -0,0 +1,2898 @@ +{ + "id": "d7f9a8ea-f8b4-42f7-89b1-5c24c822b28f", + "prevId": "00000000-0000-0000-0000-000000000000", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.admin_sessions": { + "name": "admin_sessions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "admin_id": { + "name": "admin_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "session_token": { + "name": "session_token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires": { + "name": "expires", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "admin_sessions_session_token_unique": { + "name": "admin_sessions_session_token_unique", + "nullsNotDistinct": false, + "columns": [ + "session_token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.admins": { + "name": "admins", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "username": { + "name": "username", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false, + "default": "'admin'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "last_login": { + "name": "last_login", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "admins_username_unique": { + "name": "admins_username_unique", + "nullsNotDistinct": false, + "columns": [ + "username" + ] + } + }, + "policies": {}, + "checkConstraints": { + "admins_role_check": { + "name": "admins_role_check", + "value": "(role)::text = ANY (ARRAY['super_admin','admin','support'])" + } + }, + "isRLSEnabled": false + }, + "public.password_resets": { + "name": "password_resets", + "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": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "used_at": { + "name": "used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "password_resets_token_unique": { + "name": "password_resets_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.member_profiles": { + "name": "member_profiles", + "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": true + }, + "family_id": { + "name": "family_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "bio": { + "name": "bio", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "avatar_url": { + "name": "avatar_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_public": { + "name": "is_public", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "member_profiles_slug_idx": { + "name": "member_profiles_slug_idx", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "member_profiles_user_id_unique": { + "name": "member_profiles_user_id_unique", + "nullsNotDistinct": false, + "columns": [ + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.product_clicks": { + "name": "product_clicks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "product_id": { + "name": "product_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "clicked_at": { + "name": "clicked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "referrer": { + "name": "referrer", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_hash": { + "name": "ip_hash", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "product_clicks_product_idx": { + "name": "product_clicks_product_idx", + "columns": [ + { + "expression": "product_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "clicked_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.recommended_products": { + "name": "recommended_products", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "profile_id": { + "name": "profile_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "image_url": { + "name": "image_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'general'" + }, + "display_order": { + "name": "display_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "recommended_products_profile_idx": { + "name": "recommended_products_profile_idx", + "columns": [ + { + "expression": "profile_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "display_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ai_usage": { + "name": "ai_usage", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "family_id": { + "name": "family_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "intent": { + "name": "intent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model_used": { + "name": "model_used", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prompt_tokens": { + "name": "prompt_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "completion_tokens": { + "name": "completion_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "total_tokens": { + "name": "total_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cost_estimate_paise": { + "name": "cost_estimate_paise", + "type": "numeric(10, 4)", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "ai_usage_created_idx": { + "name": "ai_usage_created_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "ai_usage_family_idx": { + "name": "ai_usage_family_idx", + "columns": [ + { + "expression": "family_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.chat_messages": { + "name": "chat_messages", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "session_id": { + "name": "session_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "varchar(20)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.chat_sessions": { + "name": "chat_sessions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "child_id": { + "name": "child_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'New conversation'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_log": { + "name": "audit_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "family_id": { + "name": "family_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "varchar(50)", + "primaryKey": false, + "notNull": true + }, + "resource_type": { + "name": "resource_type", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(45)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audit_family_idx": { + "name": "audit_family_idx", + "columns": [ + { + "expression": "family_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_audit_log_action": { + "name": "idx_audit_log_action", + "columns": [ + { + "expression": "action", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_audit_log_created": { + "name": "idx_audit_log_created", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_audit_log_family": { + "name": "idx_audit_log_family", + "columns": [ + { + "expression": "family_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_audit_log_user": { + "name": "idx_audit_log_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.log_corrections": { + "name": "log_corrections", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "family_id": { + "name": "family_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "dose_id": { + "name": "dose_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "original_value": { + "name": "original_value", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "corrected_value": { + "name": "corrected_value", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "corrected_by": { + "name": "corrected_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "log_corrections_dose_idx": { + "name": "log_corrections_dose_idx", + "columns": [ + { + "expression": "dose_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.accounts": { + "name": "accounts", + "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": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_account_id": { + "name": "provider_account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "token_type": { + "name": "token_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "session_state": { + "name": "session_state", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "accounts_provider_idx": { + "name": "accounts_provider_idx", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sessions": { + "name": "sessions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "session_token": { + "name": "session_token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "expires": { + "name": "expires", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sessions_session_token_unique": { + "name": "sessions_session_token_unique", + "nullsNotDistinct": false, + "columns": [ + "session_token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "password_hash": { + "name": "password_hash", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "password_updated_at": { + "name": "password_updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_email_unique": { + "name": "users_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verification_tokens": { + "name": "verification_tokens", + "schema": "", + "columns": { + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires": { + "name": "expires", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "verification_tokens_idx": { + "name": "verification_tokens_idx", + "columns": [ + { + "expression": "identifier", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.children": { + "name": "children", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "family_id": { + "name": "family_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "birth_date": { + "name": "birth_date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "sex": { + "name": "sex", + "type": "child_sex", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "stage": { + "name": "stage", + "type": "child_stage", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'newborn'" + }, + "image_url": { + "name": "image_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "children_family_idx": { + "name": "children_family_idx", + "columns": [ + { + "expression": "family_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.families": { + "name": "families", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tier": { + "name": "tier", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false, + "default": "'free'" + }, + "max_children": { + "name": "max_children", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 1 + }, + "max_members": { + "name": "max_members", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 2 + }, + "pediatrician_phone": { + "name": "pediatrician_phone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.family_invites": { + "name": "family_invites", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "family_id": { + "name": "family_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "member_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'viewer'" + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "invite_token_idx": { + "name": "invite_token_idx", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "family_invites_token_unique": { + "name": "family_invites_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.family_members": { + "name": "family_members", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "family_id": { + "name": "family_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "member_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'caregiver'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "family_members_family_id_user_id_key": { + "name": "family_members_family_id_user_id_key", + "columns": [ + { + "expression": "family_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.attachments": { + "name": "attachments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "family_id": { + "name": "family_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "log_entry_id": { + "name": "log_entry_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "r2_key": { + "name": "r2_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "r2_thumbnail_key": { + "name": "r2_thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "size_bytes": { + "name": "size_bytes", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "uploaded_by": { + "name": "uploaded_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "attachments_family_idx": { + "name": "attachments_family_idx", + "columns": [ + { + "expression": "family_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.memories": { + "name": "memories", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "family_id": { + "name": "family_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "child_id": { + "name": "child_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "taken_at": { + "name": "taken_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "r2_key": { + "name": "r2_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "r2_thumbnail_key": { + "name": "r2_thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "size_bytes": { + "name": "size_bytes", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "vision_caption": { + "name": "vision_caption", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "vision_tags": { + "name": "vision_tags", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "vision_embedding": { + "name": "vision_embedding", + "type": "vector(1536)", + "primaryKey": false, + "notNull": false + }, + "is_private": { + "name": "is_private", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "processing_status": { + "name": "processing_status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'uploading'" + }, + "uploaded_by": { + "name": "uploaded_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "memories_family_idx": { + "name": "memories_family_idx", + "columns": [ + { + "expression": "family_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "memories_child_idx": { + "name": "memories_child_idx", + "columns": [ + { + "expression": "child_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "memories_embedding_idx": { + "name": "memories_embedding_idx", + "columns": [ + { + "expression": "vision_embedding", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "vector_cosine_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "ivfflat", + "with": { + "lists": 100 + } + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.diapers_logs": { + "name": "diapers_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "child_id": { + "name": "child_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "diaper_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "logged_at": { + "name": "logged_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "diapers_logs_child_id_children_id_fk": { + "name": "diapers_logs_child_id_children_id_fk", + "tableFrom": "diapers_logs", + "tableTo": "children", + "columnsFrom": [ + "child_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.feeds": { + "name": "feeds", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "child_id": { + "name": "child_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "feed_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "method": { + "name": "method", + "type": "feed_method", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "amount_ml": { + "name": "amount_ml", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "logged_at": { + "name": "logged_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "feeds_child_id_children_id_fk": { + "name": "feeds_child_id_children_id_fk", + "tableFrom": "feeds", + "tableTo": "children", + "columnsFrom": [ + "child_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.growth": { + "name": "growth", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "child_id": { + "name": "child_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "measured_at": { + "name": "measured_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "weight_kg": { + "name": "weight_kg", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "height_cm": { + "name": "height_cm", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "head_circumference_cm": { + "name": "head_circumference_cm", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "growth_child_id_children_id_fk": { + "name": "growth_child_id_children_id_fk", + "tableFrom": "growth", + "tableTo": "children", + "columnsFrom": [ + "child_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.medications": { + "name": "medications", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "child_id": { + "name": "child_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dosage": { + "name": "dosage", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "frequency": { + "name": "frequency", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start_date": { + "name": "start_date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "end_date": { + "name": "end_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "medications_child_id_children_id_fk": { + "name": "medications_child_id_children_id_fk", + "tableFrom": "medications", + "tableTo": "children", + "columnsFrom": [ + "child_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.milestone_achievements": { + "name": "milestone_achievements", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "child_id": { + "name": "child_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "family_id": { + "name": "family_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "milestone_key": { + "name": "milestone_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "achieved_at": { + "name": "achieved_at", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "milestone_child_idx": { + "name": "milestone_child_idx", + "columns": [ + { + "expression": "child_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "milestone_achievements_child_milestone_unique": { + "name": "milestone_achievements_child_milestone_unique", + "columns": [ + { + "expression": "child_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "milestone_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sleeps": { + "name": "sleeps", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "child_id": { + "name": "child_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "sleep_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "ended_at": { + "name": "ended_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "duration_minutes": { + "name": "duration_minutes", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "logged_at": { + "name": "logged_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "sleeps_child_id_children_id_fk": { + "name": "sleeps_child_id_children_id_fk", + "tableFrom": "sleeps", + "tableTo": "children", + "columnsFrom": [ + "child_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.vaccinations": { + "name": "vaccinations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "child_id": { + "name": "child_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "vaccine_name": { + "name": "vaccine_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scheduled_date": { + "name": "scheduled_date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "given_date": { + "name": "given_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "lot_number": { + "name": "lot_number", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "vaccinations_child_id_children_id_fk": { + "name": "vaccinations_child_id_children_id_fk", + "tableFrom": "vaccinations", + "tableTo": "children", + "columnsFrom": [ + "child_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.allergies": { + "name": "allergies", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "child_id": { + "name": "child_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "severity": { + "name": "severity", + "type": "varchar(50)", + "primaryKey": false, + "notNull": false, + "default": "'mild'" + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.doctor_visits": { + "name": "doctor_visits", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "child_id": { + "name": "child_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "doctor_name": { + "name": "doctor_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "visit_date": { + "name": "visit_date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.illness_logs": { + "name": "illness_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "child_id": { + "name": "child_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "start_date": { + "name": "start_date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "end_date": { + "name": "end_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.medication_doses": { + "name": "medication_doses", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "medicine_id": { + "name": "medicine_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "family_id": { + "name": "family_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "administered_at": { + "name": "administered_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "administered_by": { + "name": "administered_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "amount_given": { + "name": "amount_given", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "medication_doses_family_idx": { + "name": "medication_doses_family_idx", + "columns": [ + { + "expression": "family_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "medication_doses_medicine_idx": { + "name": "medication_doses_medicine_idx", + "columns": [ + { + "expression": "medicine_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.medicines": { + "name": "medicines", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "child_id": { + "name": "child_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "dose": { + "name": "dose", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reminder_time": { + "name": "reminder_time", + "type": "varchar(10)", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.support_responses": { + "name": "support_responses", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "ticket_id": { + "name": "ticket_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "admin_id": { + "name": "admin_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.support_tickets": { + "name": "support_tickets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "family_id": { + "name": "family_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "subject": { + "name": "subject", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false, + "default": "'open'" + }, + "priority": { + "name": "priority", + "type": "varchar(20)", + "primaryKey": false, + "notNull": false, + "default": "'normal'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "support_tickets_status_check": { + "name": "support_tickets_status_check", + "value": "(status)::text = ANY (ARRAY['open','in_progress','resolved','closed'])" + }, + "support_tickets_priority_check": { + "name": "support_tickets_priority_check", + "value": "(priority)::text = ANY (ARRAY['low','normal','high','urgent'])" + } + }, + "isRLSEnabled": false + } + }, + "enums": { + "public.child_sex": { + "name": "child_sex", + "schema": "public", + "values": [ + "male", + "female", + "other" + ] + }, + "public.child_stage": { + "name": "child_stage", + "schema": "public", + "values": [ + "newborn", + "infant", + "solids_start", + "toddler_early", + "toddler_late", + "preschool" + ] + }, + "public.member_role": { + "name": "member_role", + "schema": "public", + "values": [ + "admin", + "caregiver", + "viewer" + ] + }, + "public.diaper_type": { + "name": "diaper_type", + "schema": "public", + "values": [ + "wet", + "dirty", + "both", + "dry" + ] + }, + "public.feed_method": { + "name": "feed_method", + "schema": "public", + "values": [ + "bottle", + "breast_left", + "breast_right", + "breast_both", + "cup", + "spoon", + "finger", + "self" + ] + }, + "public.feed_type": { + "name": "feed_type", + "schema": "public", + "values": [ + "breast_milk", + "formula", + "solid", + "water", + "other" + ] + }, + "public.sleep_type": { + "name": "sleep_type", + "schema": "public", + "values": [ + "nap", + "night" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json new file mode 100644 index 0000000..71d695e --- /dev/null +++ b/drizzle/meta/_journal.json @@ -0,0 +1,13 @@ +{ + "version": "7", + "dialect": "postgresql", + "entries": [ + { + "idx": 0, + "version": "7", + "when": 1779518962214, + "tag": "0000_baseline_prod_2026_05_19", + "breakpoints": true + } + ] +} \ No newline at end of file