Relationship documentation app for Z & T. Serverless SPA with Firebase backend.
- Runtime: Bun
- Frontend: Svelte 4 + Vite + TypeScript
- Styling: Tailwind CSS
- Backend: Firebase (Auth, Firestore, Hosting)
- External APIs: TMDB (movies/TV metadata)
bun installCopy the example config file and add your API keys:
cp src/lib/config.example.ts src/lib/config.tsNote: config.ts is gitignored to prevent committing API keys. You must set this up manually.
- Go to Firebase Console
- Select your existing project (or create one)
- Enable Authentication → Sign-in method → Google
- Enable Firestore Database (start in test mode, we'll lock it down)
- Go to Project Settings → General → Your apps → Add web app
- Copy the config values to
src/lib/config.ts
- Create account at TMDB
- Go to Settings → API → Create API key
- Add key to
src/lib/config.ts
- Go to GitHub Settings → Personal Access Tokens
- Create a fine-grained token with "Issues: Read and write" access for this repository
- Add token to
src/lib/config.tsundergithubConfig.token
bun add -g firebase-tools
firebase login
firebase use YOUR_PROJECT_ID
firebase deploy --only firestore:rulesbun devThe project is configured with GitHub Actions for automatic deployment:
- Production Deployment: Automatically deploys to Firebase Hosting when changes are pushed to the
mainbranch - Preview Deployment: Automatically creates preview deployments for pull requests
Setup Required:
- Go to your Firebase project → Project Settings → Service Accounts
- Click "Generate New Private Key" to download a service account JSON file
- In your GitHub repository, go to Settings → Secrets and Variables → Actions
- Create a new secret named
FIREBASE_SERVICE_ACCOUNT_ANTZ_ANTZ - Paste the entire content of the service account JSON file as the secret value
Once configured, deployments will happen automatically on every push to main.
For local manual deployment (requires Firebase CLI authentication):
npm run deploy
# or with bun
bun run deploysrc/
├── lib/
│ ├── components/
│ │ └── UserToggle.svelte # Z/T identity switch
│ ├── pages/
│ │ ├── Home.svelte
│ │ ├── Login.svelte
│ │ ├── Media.svelte # TV/Movies/Games tracking
│ │ ├── Notes.svelte # Freeform notes
│ │ ├── Places.svelte # POIs/Restaurants
│ │ └── Profiles.svelte # Partner profiles (individual preferences)
│ ├── stores/
│ │ └── app.ts # Svelte stores (auth, user prefs)
│ ├── config.ts # Firebase + TMDB config
│ ├── firebase.ts # Firebase SDK wrapper
│ └── types.ts # TypeScript interfaces
├── App.svelte # Root component + routing
├── app.css # Tailwind imports + CSS vars
└── main.ts # Entry point
type: "note"title: stringcontent: stringtags: string[]createdBy: "Z" | "T"createdAt: Timestamp
type: "tv" | "movie" | "game"title: stringtmdbId: number (for movies/TV)posterPath: string | nullstatus: "queued" | "watching" | "completed" | "dropped"rating: number | nullnotes: stringprogress: { season, episode } (TV only)createdBy: "Z" | "T"
name: stringcategory: "restaurant" | "cafe" | "bar" | "attraction" | "park" | "other"notes: stringvisited: booleanvisitDates: Timestamp[]rating: number | nullcreatedBy: "Z" | "T"
category: "food" | "drinks" | "music" | "movies" | "books" | "activities" | "scents" | "colors" | "people" | "places" | "gifts" | "other"title: stringdescription: stringnotes?: string(optional)rating?: number (1-5 scale)isFavorite?: boolean(optional)createdBy: "Z" | "T"
Each identity (Z/T) has independent preferences stored in localStorage:
theme: "light" | "dark"accentColor: hex stringname: display name
Toggle between identities via the header switch. Preferences apply immediately.