390 lines
5.6 KiB
Markdown
390 lines
5.6 KiB
Markdown
# 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 <token>
|
||
|
||
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: <token>
|
||
|
||
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
|
||
|
||
---
|
||
|
||
# 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.
|