# Calendar & Contacts API ## 1. Purpose This system is a production‑grade Calendar and Contacts REST API written in Go. It is designed for: * Human users (web/mobile frontends) * AI agents (programmatic automation) * Future SaaS expansion * High‑integrity multi‑user environments The API must be stateless, secure, permission‑enforced, timezone‑safe, and scalable. This document defines EXACTLY what must be built. --- # 2. System Architecture Client (Web / Mobile / Agent) ↓ HTTP REST API (Go + Chi) ↓ Service Layer (Business Logic) ↓ Repository Layer (SQL via sqlc) ↓ PostgreSQL Optional components: * Redis (rate limiting + job queue) * Background Worker (reminders) * S3-compatible storage (attachments) * WebSocket server (real-time updates) --- # 3. Core Design Principles 1. Stateless authentication (JWT or API key) 2. Strict ownership validation 3. All timestamps stored in UTC 4. RFC3339 format for API 5. Soft deletion instead of hard deletion 6. No trust in client-provided ownership fields 7. Clear separation between handlers, services, repositories 8. Indexes on all high-query columns --- # 4. Technology Stack Language: Go 1.22+ Router: Chi Database: PostgreSQL 15+ Query Layer: sqlc Migrations: golang-migrate Auth: JWT (github.com/golang-jwt/jwt/v5) Password hashing: bcrypt UUID: google/uuid Background jobs: Asynq (Redis) WebSockets: gorilla/websocket (optional) RRULE: rrule-go Storage: S3 compatible (MinIO client) --- # 5. Authentication Model Two authentication modes must be implemented. ## 5.1 User Authentication * Email + password * Password hashed with bcrypt (cost 12+) * JWT access token (15 min expiration) * Refresh token (7–30 days) JWT payload: { "user_id": "uuid", "exp": unix_timestamp } All protected endpoints require: Authorization: Bearer Middleware must: * Validate signature * Validate expiration * Inject user_id into request context --- ## 5.2 Agent Authentication (API Keys) Agents must be able to: * Create account * Generate API key * Perform scoped operations API keys: * Random 32+ byte token * Only hash stored in DB * Sent via header: X-API-Key: Scopes example: { "calendars": ["read", "write"], "events": ["read", "write"], "contacts": ["read", "write"] } Middleware must validate scope before allowing access. --- # 6. Data Model Overview ## Users * id (uuid) * email (unique) * password_hash * timezone * is_active * created_at * updated_at * deleted_at ## API Keys * id (uuid) * user_id * name * key_hash * scopes (jsonb) * created_at * revoked_at ## Calendars * id (uuid) * owner_id * name * color * is_public * public_token * created_at * updated_at * deleted_at ## Calendar Members * calendar_id * user_id * role (owner/editor/viewer) ## Events * id (uuid) * calendar_id * title * description * location * start_time (UTC) * end_time (UTC) * timezone * all_day * recurrence_rule * created_by * updated_by * created_at * updated_at * deleted_at ## Event Reminders * id * event_id * minutes_before ## Event Attendees * id * event_id * user_id (nullable) * email (nullable) * status ## Contacts * id * owner_id * first_name * last_name * email * phone * company * notes * created_at * updated_at * deleted_at --- # 7. Full REST Endpoint Specification All endpoints return JSON. All errors return structured error format. Error format: { "error": "string", "code": "string", "details": "optional" } --- # AUTH POST /auth/register POST /auth/login POST /auth/refresh POST /auth/logout GET /auth/me --- # API KEYS POST /api-keys GET /api-keys DELETE /api-keys/{id} --- # USERS GET /users/me PUT /users/me DELETE /users/me --- # CALENDARS GET /calendars POST /calendars GET /calendars/{id} PUT /calendars/{id} DELETE /calendars/{id} Sharing POST /calendars/{id}/share GET /calendars/{id}/members DELETE /calendars/{id}/members/{user_id} --- # EVENTS GET /events GET /events/{id} POST /events PUT /events/{id} DELETE /events/{id} Filters: GET /events?start=...&end=... GET /events?calendar_id=... GET /events?search=... GET /events?tag=... --- # REMINDERS POST /events/{id}/reminders DELETE /events/{id}/reminders/{id} --- # ATTENDEES POST /events/{id}/attendees PUT /events/{id}/attendees/{id} DELETE /events/{id}/attendees/{id} --- # CONTACTS GET /contacts POST /contacts GET /contacts/{id} PUT /contacts/{id} DELETE /contacts/{id} GET /contacts?search=... --- # AVAILABILITY GET /availability?calendar_id=...&start=...&end=... --- # BOOKING POST /calendars/{id}/booking-link GET /booking/{token}/availability POST /booking/{token}/reserve --- # ICS GET /calendars/{id}/export.ics POST /calendars/import POST /calendars/import-url GET /cal/{token}/feed.ics (public, no auth) --- # 8. Index Requirements Required indexes: * events(calendar_id, start_time) * events(start_time) * calendars(owner_id) * contacts(owner_id) * api_keys(user_id) --- # 9. Performance Rules * All list endpoints paginated (limit + cursor) * No N+1 queries * All joins explicitly defined * Recurring events expanded lazily * Reminder queries indexed --- # 10. Security Requirements * Rate limiting middleware * UUID validation * Input validation * SQL injection safe queries * Password complexity enforcement * API key hashing --- # 11. Development Phases Phase 1 * Auth * Calendars * Events * Contacts Phase 2 * Recurrence * Reminders * Sharing Phase 3 * Booking links * Availability * ICS * WebSockets --- This file defines the full system scope. The next file (logic.md) will define detailed business rules, validation logic, permission flows, recurrence logic, reminder processing, and booking behavior.