5.6 KiB
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
- Stateless authentication (JWT or API key)
- Strict ownership validation
- All timestamps stored in UTC
- RFC3339 format for API
- Soft deletion instead of hard deletion
- No trust in client-provided ownership fields
- Clear separation between handlers, services, repositories
- 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
- 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
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.