This guide shows you how to add essential SaaS features that require zero maintenance and align with the 100-year philosophy.
The following maintenance-free SaaS features have been implemented:
- User Registration/Login: SHA256 password hashing, session-based auth
- Session Management: Auto-expiring tokens with cleanup jobs
- Multi-tenant Architecture: Complete tenant isolation with subscription limits
- Role-based Access: Owner/member roles within tenants
- Event Tracking: All user actions tracked in SQLite
- Usage Analytics: Daily/monthly summaries, top users, event timelines
- Real-time Dashboard: Live stats without external dependencies
- Data Retention: Auto-cleanup after 90 days via background jobs
- Plan Tracking: Free/paid tiers with usage limits
- Usage Enforcement: Automatic limit checking for items/users
- Subscription Status: Simple active/inactive tracking
- No Payment Processing: Track subscriptions only, integrate payment later
- SQLite-based Queue: No Redis/external queue needed
- Automatic Retries: Exponential backoff for failed jobs
- Built-in Cleanup: Session cleanup, analytics cleanup
- Extensible: Easy to add new job types
- In-memory Limits: No external store required
- Token Bucket: Smooth rate limiting algorithm
- Flexible Keys: IP, user, or tenant-based limiting
- Auto-cleanup: Old rate limit data automatically removed
- Standard Library SMTP: No external email services required
- Template System: Pre-built welcome, reset, limit emails
- Development Mode: Logs emails instead of sending in development
- Extensible: Easy to add new email templates
-- All SaaS data in one database
-- Users, tenants, subscriptions, analytics, jobs
-- ACID transactions ensure consistency
-- Single file backup/restore// No external dependencies for core features
import (
"database/sql"
"net/http"
"net/smtp"
"crypto/sha256"
"time"
)// Automatic cleanup and maintenance
// Retry failed jobs with backoff
// No cron jobs or external schedulers needed// All analytics data stays local
// No third-party tracking services
// Complete data ownership# Register new user
curl -X POST /api/auth/register \
-d '{"email":"user@example.com","password":"secure123"}'
# Login
curl -X POST /api/auth/login \
-d '{"email":"user@example.com","password":"secure123"}'
# Use session token in subsequent requests
curl -H "Authorization: Bearer TOKEN" /api/items# Create a new tenant/workspace
curl -X POST -H "Authorization: Bearer TOKEN" /api/tenants \
-d '{"name":"My Company"}'
# Add user to tenant
curl -X POST -H "Authorization: Bearer TOKEN" /api/tenants/1/users \
-d '{"user_id":2,"role":"member"}'# Get real-time stats
curl -H "Authorization: Bearer TOKEN" /api/analytics/stats
# Get daily usage summary
curl -H "Authorization: Bearer TOKEN" /api/analytics/daily/2024-01-15
# Get top users
curl -H "Authorization: Bearer TOKEN" /api/analytics/users/top// Enqueue custom job
jobProcessor.EnqueueJob("send_welcome_email", map[string]interface{}{
"user_email": "user@example.com",
"user_name": "John",
})
// Register custom job handler
jobProcessor.RegisterHandler("send_welcome_email", func(payload string) error {
// Process welcome email
return nil
})- ❌ No Redis for sessions/rate limiting
- ❌ No external analytics services
- ❌ No separate job queue systems
- ❌ No third-party email services (optional)
- 🧹 Session cleanup (daily)
- 🧹 Analytics data rotation (90 days)
- 🧹 Failed job retry/cleanup
- 🧹 Rate limiter memory cleanup
- 📈 SQLite handles thousands of concurrent users
- 📈 In-memory rate limiting scales with RAM
- 📈 Background jobs process automatically
- 📈 Analytics queries use efficient indexes
- 🏠 All user data stays local
- 🏠 No external API dependencies
- 🏠 No vendor lock-in
- 🏠 Easy backup/restore (single file)
-- Add to schema.sql
CREATE TABLE IF NOT EXISTS custom_feature (
id INTEGER PRIMARY KEY AUTOINCREMENT,
tenant_id INTEGER NOT NULL REFERENCES tenants(id),
data TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);// internal/feature/feature.go
package feature
type FeatureService struct {
db *sql.DB
}
func (f *FeatureService) CreateFeature(tenantID int64, data string) error {
_, err := f.db.Exec(
"INSERT INTO custom_feature (tenant_id, data) VALUES (?, ?)",
tenantID, data,
)
return err
}// In main.go
mux.HandleFunc("/api/features", requireAuth(app.featuresHandler))// Track feature usage
analytics.TrackEvent(tenantID, userID, "feature_created", map[string]interface{}{
"feature_type": "custom",
})// Schedule periodic processing
jobProcessor.RegisterHandler("process_features", handleFeatureProcessing)
jobProcessor.EnqueueDelayedJob("process_features", nil, 24*time.Hour)func (app *App) createItemHandler(w http.ResponseWriter, r *http.Request) {
// Check limits before creating
if err := app.saas.CheckItemLimit(tenantID); err != nil {
http.Error(w, "Item limit reached", 403)
return
}
// Create item...
// Track usage
app.analytics.TrackEvent(tenantID, userID, "item_created", nil)
}// Apply rate limiting to expensive operations
apiLimiter := NewRateLimiter(100, time.Hour) // 100 requests/hour
mux.Handle("/api/expensive", apiLimiter.Middleware(UserBasedKey)(expensiveHandler))// Register job handler for email notifications
jobProcessor.RegisterHandler("limit_warning", func(payload string) error {
var data map[string]string
json.Unmarshal([]byte(payload), &data)
return emailService.SendSubscriptionLimitEmail(
data["email"], data["tenant"], data["limit_type"],
)
})
// Trigger when approaching limits
if itemCount >= sub.MaxItems*0.9 { // 90% of limit
jobProcessor.EnqueueJob("limit_warning", map[string]string{
"email": userEmail,
"tenant": tenantName,
"limit_type": "item",
})
}You now have a completely maintenance-free SaaS platform with:
- ✅ User authentication & multi-tenancy
- ✅ Usage analytics & reporting
- ✅ Subscription management
- ✅ Background job processing
- ✅ Rate limiting & abuse prevention
- ✅ Email notifications
- ✅ Automatic data cleanup
- ✅ Zero external dependencies
- ✅ Single SQLite database
- ✅ Complete data ownership
Deploy it once, run it for decades! 🚀