Skip to main content

Welcome to Zen Nurture

This guide will walk you through creating your account, setting up your first baby profile, and logging your first activities. You’ll be tracking your baby’s care in under 5 minutes.
1

Create Your Account

Visit the Zen Nurture app and sign up with your email and password.
// Authentication is handled by Better Auth
// Email verification is optional by default
authClient.signUp.email({
  email: "parent@example.com",
  password: "securePassword123",
  name: "Parent Name"
});
Zen Nurture uses Better Auth with email/password authentication. No email verification is required by default, so you can start using the app immediately.
2

Create a Family

After signing in, you’ll be prompted to create a family. This is the container for all your baby profiles and activities.
convex/families.ts
// Family structure
export const createFamily = mutation({
  args: { name: v.string() },
  handler: async (ctx, args) => {
    const user = await requireAuth(ctx);
    const now = new Date().toISOString();

    const familyId = await ctx.db.insert("families", {
      name: args.name,
      ownerId: user._id,
      createdAt: now,
    });

    await ctx.db.insert("familyMembers", {
      familyId,
      userId: user._id,
      role: "owner",
      joinedAt: now,
    });

    return familyId;
  },
});
Choose a family name that makes sense to you, like “Smith Family” or “Our Little One”. You can invite other caregivers later.
3

Set Up Your Baby Profile

Now create your baby’s profile with essential information:
  • Name: Your baby’s name
  • Date of Birth: Used to calculate age and developmental milestones
  • Gender: Optional (male/female/other)
  • Timezone: For accurate time-based reminders and reports
  • Measurement Units: Choose between metric (ml, kg, cm) or imperial (oz, lb, in)
convex/events.ts
// Baby profile structure
babyProfiles: defineTable({
  familyId: v.optional(v.id("families")),
  name: v.string(),
  dob: v.string(),  // ISO date format: "YYYY-MM-DD"
  gender: v.optional(v.string()),
  timezone: v.string(),  // e.g., "America/New_York"
  measurementUnits: v.optional(v.object({
    volume: v.optional(v.string()),   // "ml" or "oz"
    weight: v.optional(v.string()),   // "kg" or "lb"
    length: v.optional(v.string()),   // "cm" or "in"
  })),
  createdAt: v.string(),
})
Make sure to select the correct timezone. This ensures that daily summaries and reminders trigger at the right local time for your family.
4

Log Your First Activity

Start tracking by logging an activity. Let’s log a feeding:

Bottle Feeding Example

// Log a bottle feed
await convex.mutation(api.events.createEvent, {
  babyId: babyProfileId,
  type: "FEED_BOTTLE",
  timestamp: new Date().toISOString(),
  payload: {
    amountMl: 120,
    contentType: "formula",  // or "breastmilk", "other"
    formulaName: "Similac Pro-Advance",
    durationMin: 15,
    notes: "Fed well, no issues"
  }
});

Other Activity Types

{
  type: "FEED_BREAST",
  payload: {
    side: "left" | "right" | "both",
    durationMin: 20,
    notes: "Latched well"
  }
}
{
  type: "DIAPER",
  payload: {
    kind: "wet" | "dirty" | "mixed" | "dry",
    texture: "solid" | "soft" | "runny" | "watery",
    color: "brown" | "yellow" | "green" | "black",
    blowout: false,
    rash: false,
    notes: "All good"
  }
}
{
  type: "SLEEP",
  payload: {
    startTs: "2024-03-15T20:00:00Z",
    endTs: "2024-03-16T02:30:00Z",
    location: "crib" | "bassinet" | "bed" | "carrier",
    notes: "Slept through the night!"
  }
}
{
  type: "MED_DOSE",
  payload: {
    medicineName: "Tylenol (Acetaminophen)",
    amount: 2.5,
    unit: "ml",
    outcome: "taken" | "skipped",
    notes: "For fever"
  }
}
All events are stored with an ISO 8601 timestamp and are automatically synced across all family members’ devices in real-time thanks to Convex.
5

Invite Family Members

Share the caregiving load by inviting other family members:
convex/families.ts
// Invite a family member by email
export const inviteCaregiver = mutation({
  args: {
    familyId: v.id("families"),
    email: v.string(),
    role: v.optional(v.string()),  // "admin" or "caregiver"
  },
  handler: async (ctx, args) => {
    // Creates an invitation valid for 7 days
    const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);
    
    const inviteId = await ctx.db.insert("familyInvitations", {
      familyId: args.familyId,
      email: args.email,
      role: args.role ?? "caregiver",
      invitedBy: user._id,
      status: "pending",
      createdAt: new Date().toISOString(),
      expiresAt: expiresAt.toISOString(),
    });
    
    return inviteId;
  },
});

Role Permissions

RolePermissions
OwnerFull access, can delete family, manage all settings
AdminCan invite/remove members, edit baby profiles, manage reminders
CaregiverCan log activities, view data, but cannot invite others
Invited members will receive a notification when they sign in. Invitations expire after 7 days for security.
6

Set Up Reminders (Optional)

Create smart reminders to stay on top of your baby’s routine:

Fixed-Time Reminders

// Remind at specific times each day
await convex.mutation(api.events.createReminderRule, {
  babyId: babyProfileId,
  category: "feeding",
  title: "Morning feeding time",
  triggerType: "fixedTimes",
  triggerConfig: {
    times: ["07:00", "11:00", "15:00", "19:00", "23:00"]
  },
  enabled: true,
  quietHoursStart: 23,  // 11 PM
  quietHoursEnd: 6      // 6 AM
});

Interval-Based Reminders

// Remind X hours after last event of a type
await convex.mutation(api.events.createReminderRule, {
  babyId: babyProfileId,
  category: "feeding",
  title: "Time to feed again",
  triggerType: "afterLastEventType",
  triggerConfig: {
    lastEventType: "FEED_BOTTLE",
    intervalHours: 3
  },
  enabled: true
});
Push notifications require setting up the CRON_SECRET and web push VAPID keys. See the Setup Guide for details.

What’s Next?

Explore Analytics

View daily summaries, weekly digests, and trend charts to understand your baby’s patterns

Ask Mora

Chat with the AI assistant to get insights: “How many times did Emma feed yesterday?”

Track Milestones

Log developmental milestones like first smile, first steps, and more

Export Your Data

Download a complete JSON export of all your baby’s data anytime

Tips for Success

The most accurate tracking happens when you log events as they occur. Zen Nurture’s mobile-friendly interface makes it easy to quickly tap and log.
Assign a caregiver to each logged event so you can see who handled each feeding, diaper change, etc. This is especially helpful with multiple caregivers.
Include notes on events when something unusual happens or to remember important details (“refused bottle” or “slept extra long”).
Check your weekly digest every Sunday to spot trends and discuss with your pediatrician.

Need Help?

If you run into issues or have questions:
  • Ask Mora (the AI assistant) for help with app features
  • Check the Setup Guide for troubleshooting
  • Review the API Reference for technical details
Zen Nurture works offline! Events are queued locally and synced automatically when you’re back online, thanks to Convex’s optimistic updates.

Build docs developers (and LLMs) love