YOUR PLATFORM is a platform for TARGET AUDIENCE. Our current goal is to GOAL.
We do not currently leverage a monorepo; this repo is only for app.YOURLINK.com. We do leverage a src/ directory.
We follow standard React/TypeScript naming conventions: camelCase for variables/functions and PascalCase for components/classes.
Our brand colors are defined in site.ts; never define colors by hand, always pull from here.
- Next.js (app, not pages)
- Tailwind (never write vanilla CSS)
- Supabase (used for both auth and database)
- Prisma (ORM)
- TypeScript (never write vanilla JS, unless absolutely necessary)
- Zustand (always use a store for state)
- Posthog
- Framer Motion (this is used for any and all motion, regardless of its complexity)
- ShadCN (this is used for any and all UI components, regardless of its complexity)
It's critical that our app feel fast. We leverage all of the great out of the box features from Next here, use onMouseDown rather than onClick where it doesn't hinder the user experience, use lots of caching, pre-fetching, states, etc. Additionally, we are very mindful of rerenders, and try to optimize servers & DBs to be as fast as possible. We always show things optimistically when possible.
That said, when we do need to load, there are a few different ways we handle this:
- Loading States: used for longer loading between pages/while fetching data on new laod that is hard to avoid. We use the COMPONENT.tsx component to handle this.
- Skeletons: used for loading states that are easy to avoid, such as loading a table of data. We use the COMPONENT.tsx component to handle this.
- In some cases, it's fine just to show a blank white page for .5 second ~ longer; use critical thinking here.
- In cases where we are sending data up to a server, we display this on the actual button, using the correct components.
-
Never Drop Data
- ❌ Never drop columns
- ❌ Never change column types
- ✅ Add new columns with defaults
- ✅ Add new tables
- ✅ Add new relations
-
Making Breaking Changes
- Add new nullable columns instead of modifying existing ones
- Use multiple migrations for complex changes
- Keep old columns temporarily when changing data structure
- Add new columns → migrate data → remove old columns (in separate PRs)
-
Local Development
# Create a new migration npx prisma migrate dev --name descriptive_name # Test your changes npm run dev
-
Before Committing
- Pre-commit hooks will automatically check for destructive changes
- Review migration files manually
- Test migrations against a copy of production data if possible
-
CI/CD Process
- Push to main triggers automatic migration deployment
- CI checks for destructive changes
- Migrations are applied automatically after validation
If something goes wrong:
-
Immediate Actions
# Revert to the last known good migration npx prisma migrate reset --preview-feature git checkout [last-known-good-commit]
-
Data Recovery
- Recent backups are maintained in Supabase
- Contact team lead before any emergency rollbacks
-
Always Add, Never Remove
- Add new columns instead of modifying existing ones
- Keep deprecated columns until data migration is complete
- Use database triggers for automatic data population
-
Testing
- Test migrations against a copy of production data
- Verify both up and down migrations
- Include migration tests in your PR
-
Documentation
- Comment complex migrations
- Update API documentation when schema changes
- Document any required application changes