Budování moderní time tracking aplikace není jen o tom napsat kód, který "nějak funguje". Jde o vytvoření škálovatelné, maintainabilní a performantní architektury, která bude růst s vaším produktem i týmem.
V tomto technickém deep-dive si rozebereme konkrétní architekturní rozhodnutí při vývoji SnapTime – time tracking aplikace s ~24,000 řádků kódu, která zvládá komplexní týmové scénáře a real-time synchronizaci.
📊 SnapTime v číslech
Velikost projektu:
- • 91 TypeScript/JavaScript souborů
- • ~23,898 řádků kódu
- • 905 celkových souborů
- • 1.1MB finální bundle size
Technické metriky:
- • Složitost: 3/5 (střední)
- • Maintainability: 4/5 (vysoká)
- • Scalability: 4/5 (vysoká)
- • Performance: 4/5 (vysoká)
🎯 Proč Next.js + Firebase pro time tracking?
Při výběru tech stacku pro SnapTime jsme měli několik požadavků:
- Real-time synchronizace – týmy potřebují vidět změny okamžitě
- Komplexní autentizace – individuální uživatelé i týmové organizace
- SEO optimalizace – marketing pages + blog musí rankovat
- Rychlý development – as a startup potřebujeme ship fast
- Škálovatelnost – od 1 uživatele po enterprise týmy
Next.js 14 s App Routerem
Klíčové výhody pro SaaS aplikaci:
- ✓ Hybrid rendering – SSR pro SEO, CSR pro interaktivitu
- ✓ Server Actions – bezpečné mutations bez API routes
- ✓ Streaming – progresivní loading komplexních dashboardů
- ✓ Image optimization – automatická optimalizace avatarů a souborů
- ✓ Middleware – auth protection na edge level
Firebase jako Backend-as-a-Service
Proč Firebase pro time tracking:
- ✓ Firestore – real-time NoSQL s offline podporou
- ✓ Firebase Auth – komplexní user management bez vlastního backendu
- ✓ Security Rules – granulární permissions na database level
- ✓ Firebase Functions – serverless computing pro background tasks
- ✓ Analytics – built-in user tracking a performance monitoring
💡 Tech Stack Breakdown
Kategorie | Technologie | Verze | Účel |
---|---|---|---|
Framework | Next.js | 14.1.0 | Full-stack React framework |
Language | TypeScript | 5.3.3 | Type safety & developer experience |
Backend | Firebase | 11.9.0 | Database, Auth, Analytics |
Styling | Tailwind CSS | 3.4.1 | Utility-first CSS framework |
State | Zustand | Latest | Lightweight state management |
Charts | Chart.js + Recharts | Latest | Data visualization |
🏗️ Architektura projektu
SnapTime používá modulární architekturu založenou na doménách. Každá složka odpovídá jedné business logice:
SnapTime/ ├── app/ # Next.js App Router │ ├── api/ # API routes & Server Actions │ │ ├── cron/ # Scheduled jobs (reminders) │ │ ├── notifications/ # Email/push notifications │ │ └── teams/ # Team management endpoints │ ├── components/ # React components │ │ ├── landing/ # Marketing components │ │ ├── settings/ # Settings UI modules │ │ └── seo/ # SEO components │ ├── firebase/ # Firebase config & services │ │ └── services/ # Domain-specific services │ ├── hooks/ # Custom React hooks │ ├── store/ # Zustand stores │ └── types/ # TypeScript definitions ├── public/ # Static assets └── scripts/ # Build & deployment scripts
Key Architectural Decisions
1. Service Layer Pattern
Veškerá komunikace s Firebase prochází přes service layer:
// firebase/services/projects.ts export const projectService = { async createProject(data: CreateProjectData) { // Validation, transformation, Firestore operations }, async getProjectsByTeam(teamId: string) { // Complex queries, caching, permissions } }
2. Type-First Development
Všechny entity mají striktní TypeScript interface:
// types/time.ts export interface TimeEntry { id: string; projectId: string; userId: string; startTime: Timestamp; endTime?: Timestamp; description: string; tags: string[]; billable: boolean; }
3. Optimistic UI s Error Handling
Time tracking vyžaduje okamžitou zpětnou vazbu:
const startTimer = async (projectId: string) => { // 1. Optimistic update setTimeEntries(prev => [...prev, tempEntry]); try { // 2. Server sync const entry = await timeService.startTimer(projectId); // 3. Replace with real data setTimeEntries(prev => prev.map(e => e.id === tempEntry.id ? entry : e )); } catch (error) { // 4. Rollback on error setTimeEntries(prev => prev.filter(e => e.id !== tempEntry.id)); toast.error('Failed to start timer'); } };
🔐 Security & Permissions
Time tracking aplikace obsahuje citlivá data. SnapTime implementuje multi-layer security:
1. Firestore Security Rules
// firestore.rules rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // Time entries can only be read/written by owner match /timeEntries/{entryId} { allow read, write: if request.auth != null && request.auth.uid == resource.data.userId; } // Team data accessible by team members match /teams/{teamId} { allow read: if request.auth != null && request.auth.uid in resource.data.memberIds; } } }
2. Next.js Middleware
// middleware.ts export function middleware(request: NextRequest) { if (request.nextUrl.pathname.startsWith('/dashboard')) { const token = request.cookies.get('session')?.value; if (!token) { return NextResponse.redirect(new URL('/login', request.url)); } } }
📊 Performance Optimizations
⚡ Performance Čísla
1.1MB
Bundle Size
<200ms
Initial Page Load
95+
Lighthouse Score
Key Performance Strategies
1. Code Splitting & Lazy Loading
- Route-based splitting – každá stránka je vlastní chunk
- Component lazy loading – heavy komponenty (grafy, exporty) se načítají on-demand
- Dynamic imports – jsPDF a XLSX se načítají až při exportu
2. Database Query Optimization
- Index optimization – všechny časté queries mají composite indexy
- Denormalization – duplikujeme data pro rychlejší reads
- Pagination – time entries se načítají po dávkách
- Real-time subscriptions – jen pro aktivní data, ne historical
3. Caching Strategy
Multi-level caching:
- • Next.js Static Generation – marketing pages a blog
- • Zustand persistence – user preferences a settings
- • Firebase offline cache – automatické offline caching
- • Browser cache – statické assety s long-term caching
🚀 Deployment & DevOps
CI/CD Pipeline
# Simplified deployment flow git push origin main ↓ Vercel triggers build ↓ TypeScript compilation ↓ Next.js optimization ↓ Deploy to Vercel Edge ↓ Firebase functions deploy ↓ Update Firestore indexes
Monitoring & Analytics
- Vercel Speed Insights – Real User Monitoring
- Firebase Analytics – User behavior tracking
- Firebase Crashlytics – Error reporting a crash detection
- Custom logging – Business-specific metriky
🛠️ Development Workflow
Local Development Setup
# Quick start git clone [repo] cd SnapTime npm install # Environment setup cp .env.example .env.local # Add Firebase config # Start dev server npm run dev # With Firebase emulators npm run dev:firebase
Code Quality Tools
Automated quality checks:
- ✓ TypeScript – Type checking na všech úrovních
- ✓ ESLint – Code style a best practices
- ✓ Prettier – Konzistentní formatting
- ✓ Husky – Pre-commit hooks
- ✓ Lint-staged – Incrementální linting
⚠️ Challenges & Lessons Learned
Firestore Query Limitations
Problém: Firestore nepodporuje complex queries jako SQL JOIN.
Řešení: Denormalizace dat a composite queries v application layer.
// Místo JOIN používáme denormalizaci interface TimeEntry { id: string; projectId: string; projectName: string; // Denormalized projectColor: string; // Denormalized userId: string; // ... }
Real-time Updates Performance
Problém: Příliš mnoho real-time subscriptions zabíjí performance.
Řešení: Selective subscriptions pouze pro aktivní data.
TypeScript Complexity
Problém: Firebase TypeScript types jsou sometimes inconsistent.
Řešení: Vlastní type wrappers a utility types.
📈 Scalability Considerations
Component | Current Limit | Scaling Strategy |
---|---|---|
Firestore Reads | 1M/day per project | Query optimization, caching |
Real-time Connections | 100K concurrent | Connection pooling, selective subs |
Vercel Functions | 10s timeout | Background jobs, queue system |
Bundle Size | 1.1MB current | Tree shaking, code splitting |
🔮 Future Architecture Improvements
Plánované optimalizace:
- Edge Computing – Přesun business logiky na Vercel Edge Functions
- GraphQL Layer – Unified API over Firebase pro complex queries
- Redis Cache – External caching pro computed data
- Micro-frontends – Možnost independent deployments
- WebAssembly – Performance-critical calculations (time aggregations)
💡 Key Takeaways pro vývojáře
✅ Co se vyplatilo:
- • TypeScript everywhere – Saves hours of debugging
- • Service layer abstraction – Easy to test and modify
- • Optimistic UI – Great UX for time tracking
- • Firebase Security Rules – Database-level permissions
- • Modular architecture – Easy onboarding for new devs
❌ Co bychom dělali jinak:
- • Více unit testů – Testing Firebase apps je complex
- • GraphQL od začátku – Pro complex data fetching
- • Better error boundaries – Pro graceful degradation
- • Performance budgets – Automated bundle size monitoring
🚀 Začínáte s podobným projektem?
Starter Template
Pro rychlý start doporučujeme tento tech stack:
# Create Next.js app with TypeScript npx create-next-app@latest my-time-tracker --typescript --tailwind --app # Add essential dependencies npm install firebase zustand react-hot-toast npm install @types/node @headlessui/react @heroicons/react # Initialize Firebase npm install -g firebase-tools firebase init
Essential Next.js Config
// next.config.js module.exports = { experimental: { appDir: true, }, images: { domains: ['firebasestorage.googleapis.com'], }, webpack: (config) => { // Optimize bundle size config.resolve.fallback = { fs: false }; return config; }, };
🔍 Chcete vidět kód v akci?
SnapTime je live example této architektury. Můžete si vyzkoušet funkcionalitu a vidět, jak se všechny tyto principy projevují v reálné aplikaci.
🆓 Pro vývojáře zdarma:
- • Neomezené projekty
- • Kalendářové zobrazení
- • Export dat (PDF/CSV)
- • Open-source inspired
💼 Enterprise features:
- • Pokročilé týmové statistiky
- • API integrace
- • Custom dashboards
- • Priority support
✅ Zdarma pro vývojáře • ✅ Production-ready • ✅ Real-world example