A video review app with slick intuitive controls to create timestamped notes on the fly. β¨
- Next.js
- Tailwind CSS
- Framer Motion
- react-intersection-observer
- react-icons
- mongoose
- react-player
- nodemailer
- universal-cookie
- nanoid
Some additional experimental features are enabled in tailwind.config.js: uniformColorPalette, extendedSpacingScale, extendedFontSizeScale
- MongoDB database
- SMTP email server
- JWT
Create a .env.local based on the .env.example for local development.
npm i && npm run dev
Routes under pages/api/ use two small higher-order wrappers from
utils/auth/withAuthenticatedUser.ts to keep authentication out of the
handler bodies:
withAuthenticatedUser(handler)β required for routes that mutate user data (auth,user,settings,project). The handler receives a thirdctxargument with{ userDoc, email, newToken }. Missing/invalid tokens short-circuit with 401; missing users short-circuit with 401.withOptionalUser(handler)β used bypages/api/note.ts, which allows guest note creation. The handler receives a discriminatedctx: either{ isGuest: true, ... null }or the full authenticated context. A token that is present but invalid still 401s β there is no silent fallback to the guest branch.
Shared-project access goes through utils/share/sharePassword.ts:
hashSharePassword(plaintext)β used bypages/api/project.tswhen creating or updating a Share document. Returnsnullfor empty input.verifySharePassword(storedHash, candidate)β used bypages/api/public_project.tswhen reading a shared project. Returns aShareAccessResultdiscriminated union:open|passwordRequired|incorrect|ok.
Note write-path goes through utils/note/noteIntake.ts:
upsertNote(input, authorId)β used bypages/api/note.ts. Creates if_idis not found, updates otherwise. On create also attaches the note id to its Project. PassnullforauthorIdto skip authorship (guest path).removeDoneProjectNotes(projectId)β used by the same handler for theREMOVE_DONE_NOTESaction; returns the surviving notes.
All three modules have unit tests under src/__test__/ that exercise
behaviour through their public interface.