Simple, clean, and efficient meeting scheduling app.
├── README.md
├── drizzle.config.ts
├── next.config.mjs
├── node_modules
├── package.json
├── src
│ ├── app
│ │ └── [ all front-end routes ]
│ ├── components
│ │ └── [ front-end components ]
│ ├── db
│ │ ├── index.ts
│ │ ├── migrations
│ │ └── schema.ts
│ ├── lib
│ └── server
│ ├── actions ( mutate or insert data )
│ │ └── [ entity ]
│ │ └── [ verb ]
│ │ └── action.ts
│ └── data ( query data )
│ └── [ entity ]
│ └── queries.ts
└── tsconfig.json- Git
- Node.js
- pnpm
- Just run
npm i -g pnpmto install.
- Just run
- Docker Desktop
- Clone this repository locally
- Navigate to the root directory and install the dependencies.
cd ZotMeetpnpm install
- Copy the example environment file:
cp .env.example .env
- Make sure Docker Desktop is running, then set up the database:
pnpm db:setup
- Start the development server
pnpm dev(runpnpm dev --hostif you want to access the server from other devices on your network)
- The app should be viewable at
localhost:3000by default.
| Command | Description |
|---|---|
pnpm db:setup |
Start database and run migrations (first time setup) |
pnpm db:start |
Start the PostgreSQL container |
pnpm db:stop |
Stop the PostgreSQL container (data persists) |
pnpm db:reset |
Reset database - removes all data and re-runs migrations |
pnpm db:generate |
Generate new migrations from schema changes |
pnpm db:migrate |
Apply pending migrations |
pnpm db:studio |
Open Drizzle Studio to browse your database |
pnpm db:seed |
Seed the database with a group and up to 20 random test users |
- Follow the Conventional Commits specification when writing commit messages.
- E.g.,
git commit -m "feat: add this feature";git commit -m "fix: fix this bug".
- E.g.,
- Keep commits and PRs atomic.
- A PR should be a single feature or bug fix.
- A commit should be a single logical change.
If you need credentials for the .env file, contact the project lead (Kyle).
After changes to the .env file, run pnpm run check to update SvelteKit's auto-generated environment variable types.
The seed script (src/db/seed.ts) creates a group called "ZotMeet Test Group" and populates it with up to 20 randomly generated users. This is useful for testing features like availability views and group dashboards without needing real accounts.
To seed:
pnpm db:seedThe script can be run multiple times — each run adds up to 20 more randomly generated members to the group, so you can keep running it to grow the group as needed.
Important: The script cannot access your session, so it has no way of knowing your user ID. After seeding, you must manually add yourself to the group:
- Open Drizzle Studio:
pnpm db:studio - Find your id (google) in the
userstable. - Insert a row into
usersInGroupwith your ID and the seeded group's ID.
ZotMeet ships as an installable PWA and is packaged for the Apple App Store through PWA Builder.
- Web App Manifest at
/manifest.webmanifest(generated bysrc/app/manifest.ts) withname,short_name,description,start_url,display: standalone,background_color,theme_color,icons(any + maskable, including a 512x512),shortcuts,categories,screenshots,prefer_related_applications,related_applications,launch_handler,scope_extensions(Google OAuth host), and optionaliarc_rating_id. - Service worker at
public/sw.js(network-first navigations, cache-first for static assets, offline fallback atpublic/offline.html). Registered viapublic/sw-register.jsin production. - Apple meta tags (
apple-mobile-web-app-capable,apple-mobile-web-app-status-bar-style,apple-touch-icon) emitted viametadata.appleWebAppandmetadata.iconsinsrc/app/layout.tsx. - Security headers (
Strict-Transport-Security,X-Content-Type-Options,X-Frame-Options,Referrer-Policy,Permissions-Policy) innext.config.mjs. - Icons generated from
public/zotmeet-logo.svgviapnpm pwa:icons(usessharp). Output goes topublic/icons/andpublic/apple-touch-icon.png. robots.txtandsitemap.xmlat the site root.
PWA Builder requires the manifest's URLs to be absolute and reachable over
HTTPS. Deployments set NEXT_PUBLIC_BASE_URL per stage in sst.config.ts
(e.g. https://zotmeet.com in production). That same variable drives Open
Graph, robots, sitemap, and invite/email links.
- Deploy the app to its public HTTPS URL.
- Visit pwabuilder.com and enter the URL.
- Set
PWA_IARC_RATING_IDafter completing the free IARC questionnaire through a participating storefront (see How IARC Works). UpdateNEXT_PUBLIC_IOS_BUNDLE_IDif PWA Builder assigns a different bundle ID. - Click
Package for stores→iOS→Generate Package. - Take note of the
Bundle IDand download the package. - Open the generated
.xcworkspacein Xcode (≥ iOS 17 SDK), runpod installinsrc/, build, and archive for distribution following the PWA Builder iOS guide.
pnpm pwa:iconsRegenerates icons under public/icons/ and store screenshots under
public/screenshots/.
This re-renders all icon sizes (72–1024), maskable icons (192, 512),
the Apple touch icon (180x180), and favicons from public/zotmeet-logo.svg.
Commit any changes under public/icons/ and public/apple-touch-icon.png.
erDiagram
users {
string id PK, FK
string email
string passwordHash
timestamp createdAt
}
groups {
uuid id PK
string name
string description
timestamp createdAt
string createdBy FK
}
usersInGroup {
string userId FK
uuid groupId FK
}
members {
uuid id PK
string displayName
}
availability {
uuid memberId FK
uuid meetingId FK
json meetingAvailabilities
enum status
}
meeting {
uuid id PK
string title
string description
string location
json dates
string meetingType
boolean scheduled
time fromTime
time toTime
string timezone
uuid groupId FK
uuid hostId FK
timestamp createdAt
}
sessions {
string id PK
timestamp expiresAt
string userId FK
string googleAccessToken
string googleRefreshToken
timestamp googleAccessTokenExpiresAt
}
oauth_accounts {
string userId FK
string providerId PK
string providerUserId PK
}
meeting ||--o{ availability : has
users ||--o{ usersInGroup : has
groups ||--o{ usersInGroup : contains
members ||--o| users : extends
members ||--o{ availability : provides
users ||--o{ sessions : has
users ||--o{ oauth_accounts : has