Compare commits
No commits in common. "5e36c8a8485b574e0abf6d7d377de39392962fad" and "8e7a3fbe35c8fab4d994e8df1e087bc7cd4dd054" have entirely different histories.
5e36c8a848
...
8e7a3fbe35
3 changed files with 215 additions and 9 deletions
|
|
@ -37,8 +37,8 @@ export async function POST(request: Request) {
|
||||||
);
|
);
|
||||||
|
|
||||||
// In production, send email with reset link
|
// In production, send email with reset link
|
||||||
console.log(`[RESET-TOKEN] user=${user.id} email=${email} token=reset_${token} expires=${expiresAt.toISOString()}`);
|
// For now, return token for testing
|
||||||
return NextResponse.json({ success: true, message: "If email exists, reset link sent" });
|
return NextResponse.json({ success: true, token: `reset_${token}`, message: "Reset link sent" });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Reset request error:", error);
|
console.error("Reset request error:", error);
|
||||||
return NextResponse.json({ success: true, message: "If email exists, reset link sent" });
|
return NextResponse.json({ success: true, message: "If email exists, reset link sent" });
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import { sql } from "@/db";
|
import { sql } from "@/db";
|
||||||
import { requireFamily, requireOwnership } from "@/lib/auth";
|
|
||||||
|
|
||||||
// IAP Vaccination Schedule (weeks from birth)
|
// IAP Vaccination Schedule (weeks from birth)
|
||||||
const IAP_SCHEDULE = [
|
const IAP_SCHEDULE = [
|
||||||
|
|
@ -34,9 +33,6 @@ const IAP_SCHEDULE = [
|
||||||
|
|
||||||
export async function GET(request: Request) {
|
export async function GET(request: Request) {
|
||||||
try {
|
try {
|
||||||
const auth = await requireFamily();
|
|
||||||
if (!auth.success) return NextResponse.json({ error: auth.error }, { status: auth.status });
|
|
||||||
|
|
||||||
const { searchParams } = new URL(request.url);
|
const { searchParams } = new URL(request.url);
|
||||||
const childId = searchParams.get("childId");
|
const childId = searchParams.get("childId");
|
||||||
|
|
||||||
|
|
@ -44,9 +40,6 @@ export async function GET(request: Request) {
|
||||||
return NextResponse.json({ error: "childId required" }, { status: 400 });
|
return NextResponse.json({ error: "childId required" }, { status: 400 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const ownership = await requireOwnership(childId, "children", "Child");
|
|
||||||
if (!ownership.success) return NextResponse.json({ error: ownership.error }, { status: ownership.status });
|
|
||||||
|
|
||||||
// Get child's birth date
|
// Get child's birth date
|
||||||
const children = await sql`
|
const children = await sql`
|
||||||
SELECT id, name, birth_date FROM children WHERE id = ${childId}
|
SELECT id, name, birth_date FROM children WHERE id = ${childId}
|
||||||
|
|
|
||||||
213
src/app/api/setup/route.ts
Normal file
213
src/app/api/setup/route.ts
Normal file
|
|
@ -0,0 +1,213 @@
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import { sql } from "@/db";
|
||||||
|
|
||||||
|
export async function GET() {
|
||||||
|
try {
|
||||||
|
// Create enums one at a time
|
||||||
|
await sql.unsafe("CREATE TYPE child_sex AS ENUM('male', 'female', 'other')").catch(() => {});
|
||||||
|
await sql.unsafe("CREATE TYPE child_stage AS ENUM('newborn', 'infant', 'solids_start', 'toddler_early', 'toddler_late', 'preschool')").catch(() => {});
|
||||||
|
await sql.unsafe("CREATE TYPE member_role AS ENUM('admin', 'caregiver', 'viewer')").catch(() => {});
|
||||||
|
|
||||||
|
// Create users table
|
||||||
|
await sql.unsafe(`
|
||||||
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
name TEXT,
|
||||||
|
email TEXT NOT NULL UNIQUE,
|
||||||
|
email_verified TIMESTAMP,
|
||||||
|
image TEXT,
|
||||||
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL,
|
||||||
|
updated_at TIMESTAMP DEFAULT NOW() NOT NULL
|
||||||
|
)
|
||||||
|
`).catch(() => {});
|
||||||
|
|
||||||
|
// Create accounts table
|
||||||
|
await sql.unsafe(`
|
||||||
|
CREATE TABLE IF NOT EXISTS accounts (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
user_id UUID NOT NULL REFERENCES users(id),
|
||||||
|
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,
|
||||||
|
UNIQUE(provider, provider_account_id)
|
||||||
|
)
|
||||||
|
`).catch(() => {});
|
||||||
|
|
||||||
|
// Create sessions table
|
||||||
|
await sql.unsafe(`
|
||||||
|
CREATE TABLE IF NOT EXISTS sessions (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
session_token TEXT NOT NULL UNIQUE,
|
||||||
|
user_id UUID NOT NULL REFERENCES users(id),
|
||||||
|
expires TIMESTAMP NOT NULL
|
||||||
|
)
|
||||||
|
`).catch(() => {});
|
||||||
|
|
||||||
|
// Create verification_tokens table
|
||||||
|
await sql.unsafe(`
|
||||||
|
CREATE TABLE IF NOT EXISTS verification_tokens (
|
||||||
|
identifier TEXT NOT NULL,
|
||||||
|
token TEXT NOT NULL,
|
||||||
|
expires TIMESTAMP NOT NULL,
|
||||||
|
UNIQUE(identifier, token)
|
||||||
|
)
|
||||||
|
`).catch(() => {});
|
||||||
|
|
||||||
|
// Create families table
|
||||||
|
await sql.unsafe(`
|
||||||
|
CREATE TABLE IF NOT EXISTS families (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL,
|
||||||
|
updated_at TIMESTAMP DEFAULT NOW() NOT NULL
|
||||||
|
)
|
||||||
|
`).catch(() => {});
|
||||||
|
|
||||||
|
// Create family_members table
|
||||||
|
await sql.unsafe(`
|
||||||
|
CREATE TABLE IF NOT EXISTS family_members (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
family_id UUID NOT NULL REFERENCES families(id),
|
||||||
|
user_id UUID NOT NULL REFERENCES users(id),
|
||||||
|
role member_role NOT NULL DEFAULT 'caregiver',
|
||||||
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL,
|
||||||
|
UNIQUE(family_id, user_id)
|
||||||
|
)
|
||||||
|
`).catch(() => {});
|
||||||
|
|
||||||
|
// Create children table
|
||||||
|
await sql.unsafe(`
|
||||||
|
CREATE TABLE IF NOT EXISTS children (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
family_id UUID NOT NULL REFERENCES families(id),
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
birth_date DATE NOT NULL,
|
||||||
|
sex child_sex,
|
||||||
|
stage child_stage NOT NULL DEFAULT 'newborn',
|
||||||
|
image_url TEXT,
|
||||||
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL,
|
||||||
|
updated_at TIMESTAMP DEFAULT NOW() NOT NULL
|
||||||
|
)
|
||||||
|
`).catch(() => {});
|
||||||
|
|
||||||
|
// Create family_invites table
|
||||||
|
await sql.unsafe(`
|
||||||
|
CREATE TABLE IF NOT EXISTS family_invites (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
family_id UUID NOT NULL REFERENCES families(id),
|
||||||
|
email TEXT NOT NULL,
|
||||||
|
role member_role NOT NULL DEFAULT 'viewer',
|
||||||
|
token TEXT NOT NULL UNIQUE,
|
||||||
|
expires_at TIMESTAMP NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL,
|
||||||
|
UNIQUE(family_id, email)
|
||||||
|
)
|
||||||
|
`).catch(() => {});
|
||||||
|
|
||||||
|
// === LOG TABLES ===
|
||||||
|
// Feed type enum
|
||||||
|
await sql.unsafe("CREATE TYPE feed_type AS ENUM('breast_milk', 'formula', 'solid', 'water', 'other')").catch(() => {});
|
||||||
|
await sql.unsafe("CREATE TYPE feed_method AS ENUM('bottle', 'breast_left', 'breast_right', 'breast_both', 'cup', 'spoon', 'finger', 'self')").catch(() => {});
|
||||||
|
await sql.unsafe("CREATE TYPE diaper_type AS ENUM('wet', 'dirty', 'both', 'dry')").catch(() => {});
|
||||||
|
await sql.unsafe("CREATE TYPE sleep_type AS ENUM('nap', 'night')").catch(() => {});
|
||||||
|
|
||||||
|
// Feeds table
|
||||||
|
await sql.unsafe(`
|
||||||
|
CREATE TABLE IF NOT EXISTS feeds (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
child_id UUID NOT NULL REFERENCES children(id),
|
||||||
|
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
|
||||||
|
)
|
||||||
|
`).catch(() => {});
|
||||||
|
|
||||||
|
// Diapers table
|
||||||
|
await sql.unsafe(`
|
||||||
|
CREATE TABLE IF NOT EXISTS diapers_logs (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
child_id UUID NOT NULL REFERENCES children(id),
|
||||||
|
type diaper_type NOT NULL,
|
||||||
|
notes TEXT,
|
||||||
|
logged_at TIMESTAMP DEFAULT NOW() NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL
|
||||||
|
)
|
||||||
|
`).catch(() => {});
|
||||||
|
|
||||||
|
// Sleeps table
|
||||||
|
await sql.unsafe(`
|
||||||
|
CREATE TABLE IF NOT EXISTS sleeps (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
child_id UUID NOT NULL REFERENCES children(id),
|
||||||
|
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
|
||||||
|
)
|
||||||
|
`).catch(() => {});
|
||||||
|
|
||||||
|
// Vaccinations table
|
||||||
|
await sql.unsafe(`
|
||||||
|
CREATE TABLE IF NOT EXISTS vaccinations (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
child_id UUID NOT NULL REFERENCES children(id),
|
||||||
|
vaccine_name TEXT NOT NULL,
|
||||||
|
scheduled_date DATE NOT NULL,
|
||||||
|
given_date DATE,
|
||||||
|
status TEXT NOT NULL DEFAULT 'pending',
|
||||||
|
provider TEXT,
|
||||||
|
lot_number TEXT,
|
||||||
|
notes TEXT,
|
||||||
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL
|
||||||
|
)
|
||||||
|
`).catch(() => {});
|
||||||
|
|
||||||
|
// Growth table
|
||||||
|
await sql.unsafe(`
|
||||||
|
CREATE TABLE IF NOT EXISTS growth (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
child_id UUID NOT NULL REFERENCES children(id),
|
||||||
|
measured_at TIMESTAMP NOT NULL,
|
||||||
|
weight_kg REAL,
|
||||||
|
height_cm REAL,
|
||||||
|
head_circumference_cm REAL,
|
||||||
|
notes TEXT,
|
||||||
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL
|
||||||
|
)
|
||||||
|
`).catch(() => {});
|
||||||
|
|
||||||
|
// Medications table
|
||||||
|
await sql.unsafe(`
|
||||||
|
CREATE TABLE IF NOT EXISTS medications (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
child_id UUID NOT NULL REFERENCES children(id),
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
dosage TEXT,
|
||||||
|
frequency TEXT,
|
||||||
|
start_date DATE NOT NULL,
|
||||||
|
end_date DATE,
|
||||||
|
active BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
notes TEXT,
|
||||||
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL
|
||||||
|
)
|
||||||
|
`).catch(() => {});
|
||||||
|
|
||||||
|
return NextResponse.json({ success: true, message: "All tables created" });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return NextResponse.json({ error: String(error) }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue