mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-07 04:12:04 +00:00
HealthLog — personal health-tracking PWA with weight, blood pressure, pulse, mood tracking, medication compliance, Withings integration, doctor report PDF export, and Dracula-themed UI.
253 lines
8.5 KiB
SQL
253 lines
8.5 KiB
SQL
-- CreateSchema
|
|
CREATE SCHEMA IF NOT EXISTS "public";
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "measurement_type" AS ENUM ('WEIGHT', 'BLOOD_PRESSURE_SYS', 'BLOOD_PRESSURE_DIA', 'PULSE', 'BODY_FAT', 'SLEEP_DURATION', 'ACTIVITY_STEPS');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "measurement_source" AS ENUM ('MANUAL', 'WITHINGS', 'IMPORT');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "intake_source" AS ENUM ('WEB', 'API', 'REMINDER');
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "users" (
|
|
"id" TEXT NOT NULL,
|
|
"username" TEXT NOT NULL,
|
|
"email" TEXT,
|
|
"password_hash" TEXT,
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updated_at" TIMESTAMP(3) NOT NULL,
|
|
"height_cm" DOUBLE PRECISION,
|
|
"timezone" TEXT NOT NULL DEFAULT 'Europe/Berlin',
|
|
"bp_sys_target_low" INTEGER,
|
|
"bp_sys_target_high" INTEGER,
|
|
"bp_dia_target_low" INTEGER,
|
|
"bp_dia_target_high" INTEGER,
|
|
"openai_key_encrypted" TEXT,
|
|
"insights_privacy_mode" TEXT NOT NULL DEFAULT 'aggregated',
|
|
"insights_cached_at" TIMESTAMP(3),
|
|
"insights_cached_text" TEXT,
|
|
|
|
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "passkeys" (
|
|
"id" TEXT NOT NULL,
|
|
"user_id" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL DEFAULT 'Passkey',
|
|
"credential_id" TEXT NOT NULL,
|
|
"credential_public_key" BYTEA NOT NULL,
|
|
"counter" BIGINT NOT NULL DEFAULT 0,
|
|
"credential_device_type" TEXT NOT NULL,
|
|
"credential_backed_up" BOOLEAN NOT NULL DEFAULT false,
|
|
"transports" TEXT[],
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "passkeys_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "sessions" (
|
|
"id" TEXT NOT NULL,
|
|
"user_id" TEXT NOT NULL,
|
|
"expires_at" TIMESTAMP(3) NOT NULL,
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"ip_address" TEXT,
|
|
"user_agent" TEXT,
|
|
|
|
CONSTRAINT "sessions_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "auth_challenges" (
|
|
"id" TEXT NOT NULL,
|
|
"user_id" TEXT,
|
|
"challenge" TEXT NOT NULL,
|
|
"type" TEXT NOT NULL,
|
|
"expires_at" TIMESTAMP(3) NOT NULL,
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "auth_challenges_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "measurements" (
|
|
"id" TEXT NOT NULL,
|
|
"user_id" TEXT NOT NULL,
|
|
"type" "measurement_type" NOT NULL,
|
|
"value" DOUBLE PRECISION NOT NULL,
|
|
"unit" TEXT NOT NULL,
|
|
"source" "measurement_source" NOT NULL DEFAULT 'MANUAL',
|
|
"measured_at" TIMESTAMP(3) NOT NULL,
|
|
"notes" TEXT,
|
|
"external_id" TEXT,
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updated_at" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "measurements_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "medications" (
|
|
"id" TEXT NOT NULL,
|
|
"user_id" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"dose" TEXT NOT NULL,
|
|
"active" BOOLEAN NOT NULL DEFAULT true,
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updated_at" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "medications_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "medication_schedules" (
|
|
"id" TEXT NOT NULL,
|
|
"medication_id" TEXT NOT NULL,
|
|
"windowStart" TEXT NOT NULL,
|
|
"windowEnd" TEXT NOT NULL,
|
|
"label" TEXT,
|
|
|
|
CONSTRAINT "medication_schedules_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "medication_intake_events" (
|
|
"id" TEXT NOT NULL,
|
|
"user_id" TEXT NOT NULL,
|
|
"medication_id" TEXT NOT NULL,
|
|
"scheduled_for" TIMESTAMP(3) NOT NULL,
|
|
"taken_at" TIMESTAMP(3),
|
|
"skipped" BOOLEAN NOT NULL DEFAULT false,
|
|
"source" "intake_source" NOT NULL DEFAULT 'WEB',
|
|
"idempotency_key" TEXT,
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "medication_intake_events_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "api_tokens" (
|
|
"id" TEXT NOT NULL,
|
|
"user_id" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"token_hash" TEXT NOT NULL,
|
|
"permissions" TEXT[] DEFAULT ARRAY['medication:ingest']::TEXT[],
|
|
"last_used_at" TIMESTAMP(3),
|
|
"expires_at" TIMESTAMP(3),
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"revoked" BOOLEAN NOT NULL DEFAULT false,
|
|
|
|
CONSTRAINT "api_tokens_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "withings_connections" (
|
|
"id" TEXT NOT NULL,
|
|
"user_id" TEXT NOT NULL,
|
|
"withings_user_id" TEXT NOT NULL,
|
|
"access_token" TEXT NOT NULL,
|
|
"refresh_token" TEXT NOT NULL,
|
|
"token_expires_at" TIMESTAMP(3) NOT NULL,
|
|
"last_synced_at" TIMESTAMP(3),
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updated_at" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "withings_connections_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "audit_logs" (
|
|
"id" TEXT NOT NULL,
|
|
"user_id" TEXT,
|
|
"action" TEXT NOT NULL,
|
|
"details" TEXT,
|
|
"ip_address" TEXT,
|
|
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "audit_logs_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "users_username_key" ON "users"("username");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "passkeys_credential_id_key" ON "passkeys"("credential_id");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "sessions_user_id_idx" ON "sessions"("user_id");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "auth_challenges_user_id_idx" ON "auth_challenges"("user_id");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "measurements_user_id_type_measured_at_idx" ON "measurements"("user_id", "type", "measured_at");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "measurements_external_id_idx" ON "measurements"("external_id");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "measurements_user_id_type_measured_at_source_key" ON "measurements"("user_id", "type", "measured_at", "source");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "medications_user_id_idx" ON "medications"("user_id");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "medication_intake_events_idempotency_key_key" ON "medication_intake_events"("idempotency_key");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "medication_intake_events_user_id_medication_id_scheduled_fo_idx" ON "medication_intake_events"("user_id", "medication_id", "scheduled_for");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "api_tokens_token_hash_key" ON "api_tokens"("token_hash");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "api_tokens_user_id_idx" ON "api_tokens"("user_id");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "withings_connections_user_id_key" ON "withings_connections"("user_id");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "audit_logs_user_id_created_at_idx" ON "audit_logs"("user_id", "created_at");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "audit_logs_action_created_at_idx" ON "audit_logs"("action", "created_at");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "passkeys" ADD CONSTRAINT "passkeys_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "sessions" ADD CONSTRAINT "sessions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "auth_challenges" ADD CONSTRAINT "auth_challenges_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "measurements" ADD CONSTRAINT "measurements_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "medications" ADD CONSTRAINT "medications_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "medication_schedules" ADD CONSTRAINT "medication_schedules_medication_id_fkey" FOREIGN KEY ("medication_id") REFERENCES "medications"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "medication_intake_events" ADD CONSTRAINT "medication_intake_events_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "medication_intake_events" ADD CONSTRAINT "medication_intake_events_medication_id_fkey" FOREIGN KEY ("medication_id") REFERENCES "medications"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "api_tokens" ADD CONSTRAINT "api_tokens_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "withings_connections" ADD CONSTRAINT "withings_connections_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "audit_logs" ADD CONSTRAINT "audit_logs_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|