Skip to content

Commit

Permalink
Merge pull request #45 from lilith/mv-uility-funcs
Browse files Browse the repository at this point in the history
Mv uility funcs
  • Loading branch information
jho44 authored Aug 3, 2023
2 parents 4a3b0bd + f886565 commit d5eb083
Show file tree
Hide file tree
Showing 19 changed files with 577 additions and 269 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
# playdate
[![Run Tests](https://github.com/lilith/playdate/actions/workflows/test.yml/badge.svg)](https://github.com/lilith/playdate/actions/workflows/test.yml)

[![Run Tests](https://github.com/lilith/playdate/actions/workflows/test.yml/badge.svg)](https://github.com/lilith/playdate/actions/workflows/test.yml)

_get texts when your kid's friends are free. broadcast texts to their parents when you're free. save time automatically. schedule easier. build friendships. make memories._

[playdate.help](https://playdate.help) saves time and helps build friendships by coordinating tentative availability between parents for playdates. It's open-source (AGPLv3) and non-commercial.


The [design document draft is here](https://docs.google.com/document/d/18AJJTOX9x-pXl4mSTfKHp_9Op4cszZLhZkb9UiQZbNA/edit?usp=sharing) (comment and edit!)

ideal tech stack: SvelteKit, Twilio, PostgreSQL, Vercel (If too slow, DigitalOcean/Heroku/app platform).
Expand Down
2 changes: 1 addition & 1 deletion playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const config: PlaywrightTestConfig = {
expect: {
timeout: 3000
},
timeout: 20000,
timeout: 5000,
testDir: 'tests'
};

Expand Down
80 changes: 79 additions & 1 deletion prisma/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ async function main() {
'+12015550122',
'+12015550123',
'+12015550124',
'+12015550125'
'+12015550125',
'+12015550126'
];
const now = new Date();
const expires = new Date();
Expand Down Expand Up @@ -48,6 +49,35 @@ async function main() {
};
}

function householdWithKid(ind: number, kidInd: number) {
return {
household: {
connectOrCreate: {
where: {
id: ind
},
create: {
id: ind,
name: `Household ${ind}`,
children: {
connectOrCreate: [
{
where: {
id: kidInd
},
create: {
firstName: `User ${ind} Kid ${kidInd}`,
pronouns: Pronoun['HE_HIM_HIS']
}
}
]
}
}
}
}
};
}

function basicUser(id: number) {
return {
firstName: `User ${id}`,
Expand All @@ -60,6 +90,10 @@ async function main() {
};
}

await prisma.friendRequest
.deleteMany()
.catch(() => console.log('No friend request table to delete'));

// User 1
await prisma.user.upsert({
where: {
Expand Down Expand Up @@ -207,6 +241,50 @@ async function main() {
update: householdInvite,
create: householdInvite
});

// User 6
const user6 = {
...basicUser(6),
...householdWithKid(6, 1)
};

await prisma.user.upsert({
where: {
phone: phones[5]
},
update: user6,
create: {
...user6,
...permsYes(phones[5])
}
});

const kid1 = {
householdId: 6,
firstName: 'User 6 Kid 1',
pronouns: Pronoun['HE_HIM_HIS']
};
await prisma.householdChild.upsert({
where: {
id: 1
},
update: kid1,
create: kid1
});

const user6session = 'user6session';
const session6 = {
token: user6session,
phone: phones[5],
expires
};
await prisma.session.upsert({
where: {
token: user6session
},
update: session6,
create: session6
});
}

export async function run() {
Expand Down
8 changes: 6 additions & 2 deletions src/hooks.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@ export const handle = (async ({ event, resolve }) => {
!event.url.pathname.startsWith('/legal/') &&
event.url.pathname.slice(0, 6) !== '/login' &&
event.url.pathname !== '/reminder' &&
event.url.pathname !== '/twilio' &&
event.url.pathname !== '/sanitize'
!(event.url.pathname === '/twilio' && event.url.searchParams.get('nocookie'))
) {
if (!cookie) throw redirect(303, '/');
const session = await prisma.session.findUnique({
Expand Down Expand Up @@ -129,6 +128,11 @@ export const handle = (async ({ event, resolve }) => {
return response;
}

if (event.url.pathname === '/twilio' && event.url.searchParams.get('noacc')) {
// user has session token but no account
return await resolve(event);
}

await setLocal(user, session.phone, event);

// F-C, if their profile has no name, pronouns, zone, language, or accepted_terms_on date, or notification specification
Expand Down
5 changes: 2 additions & 3 deletions src/lib/server/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { error } from '@sveltejs/kit';

import { AvailabilityStatus, PrismaClient, type Pronoun } from '@prisma/client';
import type { User } from '@prisma/client';
import { construct_svelte_component_dev } from 'svelte/internal';

const prisma = new PrismaClient();

Expand Down Expand Up @@ -360,7 +359,7 @@ async function createHouseholdInvite(
) {
const { targetPhone } = req;
const { id: fromUserId } = user;
let { householdId } = user;
const { householdId } = user;
if (!householdId) {
throw error(401, {
message: 'You need to create / join a household before inviting others to join it.'
Expand Down Expand Up @@ -553,7 +552,7 @@ async function saveKid(
user: User
) {
const { firstName, pronouns, lastName, dateOfBirth } = req;
let { householdId } = user;
const { householdId } = user;
// ensure the household exists before adding kid to it
if (!householdId) {
throw error(401, {
Expand Down
54 changes: 54 additions & 0 deletions src/lib/server/sanitize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { PrismaClient, Pronoun, type User } from '@prisma/client';
import { error } from '@sveltejs/kit';
const prisma = new PrismaClient();
import sanitizerFunc from 'sanitize';

const sanitizer = sanitizerFunc();

type PRONOUNS_ENUM = keyof typeof Pronoun;

export const getParams = (url: URL, paramNames: string[]) => {
const params = paramNames.map((x) => url.searchParams.get(x)).filter(Boolean) as string[];
if (params.length < paramNames.length) return null;
return params;
};

const sanitize = (input: string) => sanitizer.value(input, 'str');

export const circleNotif = async (schedDiffs: string, user: User) => {
const sanitizedSchedDiffs = sanitize(schedDiffs);
let objectivePronoun = Pronoun[user.pronouns as PRONOUNS_ENUM].split('_')[2];
const { SHE_HER_HERS, THEY_THEM_THEIRS, XE_XEM_XYRS, ZEZIE_HIR_HIRS } = Pronoun;
// turn from possessive noun to possessive adjective
switch (user.pronouns) {
case SHE_HER_HERS:
case THEY_THEM_THEIRS:
case XE_XEM_XYRS:
case ZEZIE_HIR_HIRS:
objectivePronoun = objectivePronoun.slice(0, -1).toLowerCase();
}

let kidNames = '';

if (!user.householdId) {
throw error(400, {
message:
'You need to be part of a household in order to send notifs about your updated calendar'
});
}
const kids = await prisma.householdChild.findMany({
where: {
householdId: user.householdId
}
});

kidNames = kids
.map((kid) => `${kid.firstName}${kid.lastName ? ` ${kid.lastName}` : ''}`)
.join(', ');

return `${user.firstName}${
user.lastName && user.lastName.length ? ` ${user.lastName}` : ''
} (parent of ${kidNames}) has updated ${objectivePronoun} tentative schedule:\nLegend: 🏠(host) 🚗(visit) 👤(dropoff) 👥(together) 🏫(at school) ⭐(good) 🌟(great) 🙏(needed)\n\n${sanitizedSchedDiffs}`;
};

export const dateNotes = (notes: string) => sanitize(notes);
1 change: 1 addition & 0 deletions src/lib/server/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { Session } from '@prisma/client';
const prisma = new PrismaClient();

async function getProfileFromSession(sessionToken: string) {
if (!sessionToken) return { user: null, phone: null };
const session = (await prisma.session.findUnique({
where: {
token: sessionToken
Expand Down
Loading

0 comments on commit d5eb083

Please sign in to comment.