|
1 | | -# API Documentation |
| 1 | +# Database Design |
2 | 2 |
|
3 | | -## Overview |
| 3 | +This document outlines the database structure for the **Device Telemetry API**, showing tables, column types, relationships, and example data. |
4 | 4 |
|
5 | | -This API allows registering devices, sending commands, and retrieving telemetry data. |
6 | | -All requests and responses are in **JSON**. |
7 | | -Base URL: |
| 5 | +## **1. Users Table** |
8 | 6 |
|
9 | | -``` |
10 | | -/api/v1 |
11 | | -``` |
12 | | - |
13 | | -## Authentication |
14 | | - |
15 | | -All endpoints (except `/auth/register` and `/auth/login`) require authentication via Bearer token: |
16 | | - |
17 | | -``` |
18 | | -Authorization: Bearer <JWT_TOKEN> |
19 | | -``` |
20 | | - |
21 | | -## **Auth Routes** |
22 | | - |
23 | | -### 1. Register User |
| 7 | +Stores user accounts and authentication info. |
24 | 8 |
|
25 | | -`POST /auth/register` |
| 9 | +| Column | Type | Notes | |
| 10 | +| ------------- | ----------- | --------------------- | |
| 11 | +| id | UUID | Primary Key | |
| 12 | +| username | VARCHAR | Unique | |
| 13 | +| email | VARCHAR | Unique | |
| 14 | +| password_hash | TEXT | Hashed password | |
| 15 | +| created_at | TIMESTAMPTZ | Account creation time | |
| 16 | +| updated_at | TIMESTAMPTZ | Last update time | |
26 | 17 |
|
27 | | -Registers a new user. |
28 | | - |
29 | | -**Request Body**: |
| 18 | +**Example:** |
30 | 19 |
|
31 | 20 | ```json |
32 | 21 | { |
33 | | - "username": "john", |
| 22 | + "id": "uuid-1234", |
| 23 | + "username": "john_doe", |
34 | 24 | "email": "john@example.com", |
35 | | - "password": "strongpassword123" |
| 25 | + "password_hash": "$2a$12$abc123hashedpassword", |
| 26 | + "created_at": "2025-08-14T12:00:00Z", |
| 27 | + "updated_at": "2025-08-14T12:00:00Z" |
36 | 28 | } |
37 | 29 | ``` |
38 | 30 |
|
39 | | -**Response** `201 Created`: |
| 31 | +## **2. Devices Table** |
| 32 | + |
| 33 | +Tracks user devices, type, status, and optional metadata. |
| 34 | + |
| 35 | +| Column | Type | Notes | |
| 36 | +| ----------- | --------- | ------------------------------------- | |
| 37 | +| id | UUID | Primary Key | |
| 38 | +| user_id | UUID | Foreign Key → Users(id) | |
| 39 | +| name | VARCHAR | Device name | |
| 40 | +| device_type | VARCHAR | E.g., temperature_sensor | |
| 41 | +| status | VARCHAR | Online / Offline | |
| 42 | +| metadata | JSONB | Flexible info like firmware, location | |
| 43 | +| created_at | TIMESTAMP | Device added time | |
| 44 | +| updated_at | TIMESTAMP | Last update time | |
| 45 | + |
| 46 | +**Example:** |
40 | 47 |
|
41 | 48 | ```json |
42 | 49 | { |
43 | | - "id": "user-uuid", |
44 | | - "username": "john", |
45 | | - "email": "john@example.com" |
| 50 | + "id": "uuid-5678", |
| 51 | + "user_id": "uuid-1234", |
| 52 | + "name": "Living Room Sensor", |
| 53 | + "device_type": "temperature_sensor", |
| 54 | + "status": "Online", |
| 55 | + "metadata": { |
| 56 | + "manufacturer": "AcmeSensors", |
| 57 | + "firmware_version": "v1.2.3", |
| 58 | + "location": "Living Room" |
| 59 | + }, |
| 60 | + "created_at": "2025-08-14T12:05:00Z", |
| 61 | + "updated_at": "2025-08-14T12:30:00Z" |
46 | 62 | } |
47 | 63 | ``` |
48 | 64 |
|
49 | | -**Errors**: |
50 | | - |
51 | | -- `400 Bad Request` → invalid email/password |
52 | | -- `409 Conflict` → email already exists |
53 | | - |
54 | | -### 2. Login |
| 65 | +## **3. Telemetry Table** |
55 | 66 |
|
56 | | -`POST /auth/login` |
| 67 | +Stores sensor readings from devices. Flexible using JSONB. |
57 | 68 |
|
58 | | -Logs in a user, returns **JWT access_token** in JSON and sets a **refresh_token** in secure, HTTP-only cookie. |
| 69 | +| Column | Type | Notes | |
| 70 | +| ----------- | --------- | ------------------------- | |
| 71 | +| id | UUID | Primary Key | |
| 72 | +| device_id | UUID | Foreign Key → Devices(id) | |
| 73 | +| data_type | VARCHAR | E.g., environment, motion | |
| 74 | +| value | JSONB | Sensor readings, flexible | |
| 75 | +| recorded_at | TIMESTAMP | Timestamp of reading | |
59 | 76 |
|
60 | | -**Request Body**: |
| 77 | +**Example:** |
61 | 78 |
|
62 | 79 | ```json |
63 | 80 | { |
64 | | - "email": "john@example.com", |
65 | | - "password": "strongpassword123" |
| 81 | + "id": "uuid-9012", |
| 82 | + "device_id": "uuid-5678", |
| 83 | + "data_type": "environment", |
| 84 | + "value": { |
| 85 | + "temperature": 24.5, |
| 86 | + "humidity": 48.2, |
| 87 | + "light": 300 |
| 88 | + }, |
| 89 | + "recorded_at": "2025-08-14T12:10:00Z" |
66 | 90 | } |
67 | 91 | ``` |
68 | 92 |
|
69 | | -**Response** `200 OK`: |
| 93 | +## **4. Commands Table** |
| 94 | + |
| 95 | +Stores commands issued to devices with flexible payloads. |
| 96 | + |
| 97 | +| Column | Type | Notes | |
| 98 | +| ----------- | --------- | --------------------------- | |
| 99 | +| id | UUID | Primary Key | |
| 100 | +| device_id | UUID | Foreign Key → Devices(id) | |
| 101 | +| command | VARCHAR | Command name | |
| 102 | +| payload | JSONB | Flexible command arguments | |
| 103 | +| status | VARCHAR | Pending / Executed / Failed | |
| 104 | +| created_at | TIMESTAMP | Command issued time | |
| 105 | +| executed_at | TIMESTAMP | When executed (nullable) | |
| 106 | + |
| 107 | +**Example:** |
70 | 108 |
|
71 | 109 | ```json |
72 | 110 | { |
73 | | - "access_token": "<JWT_TOKEN>", |
74 | | - "expires_in": 3600 |
| 111 | + "id": "uuid-3456", |
| 112 | + "device_id": "uuid-5678", |
| 113 | + "command": "set_threshold", |
| 114 | + "payload": { |
| 115 | + "temperature": 25.0, |
| 116 | + "humidity": 50.0 |
| 117 | + }, |
| 118 | + "status": "Pending", |
| 119 | + "created_at": "2025-08-14T12:15:00Z", |
| 120 | + "executed_at": null |
75 | 121 | } |
76 | 122 | ``` |
77 | 123 |
|
78 | | -**Errors**: |
79 | | - |
80 | | -- `401 Unauthorized` → invalid credentials |
81 | | - |
82 | | -### 3. Refresh Token |
| 124 | +## **5. Tokens Table** |
83 | 125 |
|
84 | | -`POST /auth/refresh` |
| 126 | +Stores authentication and verification tokens securely. |
85 | 127 |
|
86 | | -Uses the **refresh token cookie** to issue a new access token. |
| 128 | +| Column | Type | Notes | |
| 129 | +| ------------ | ----------- | ---------------------------------------------------------- | |
| 130 | +| id | UUID | Primary Key | |
| 131 | +| token_hash | BYTEA | Hashed token (unique, never store plain tokens) | |
| 132 | +| user_id | UUID | Foreign Key → Users(id), cascade on delete | |
| 133 | +| scope | TEXT | Token type: `auth`, `email_verification`, `password_reset` | |
| 134 | +| revoked | BOOLEAN | Whether the token is revoked | |
| 135 | +| expires_at | TIMESTAMPTZ | Expiry timestamp | |
| 136 | +| last_used_at | TIMESTAMPTZ | When token was last used (nullable) | |
| 137 | +| created_at | TIMESTAMPTZ | Creation time | |
87 | 138 |
|
88 | | -**Response** `200 OK`: |
| 139 | +**Example:** |
89 | 140 |
|
90 | 141 | ```json |
91 | 142 | { |
92 | | - "access_token": "<NEW_JWT_TOKEN>", |
93 | | - "expires_in": 3600 |
| 143 | + "id": "uuid-7890", |
| 144 | + "token_hash": "base64-hash==", |
| 145 | + "user_id": "uuid-1234", |
| 146 | + "scope": "auth", |
| 147 | + "revoked": false, |
| 148 | + "expires_at": "2025-08-15T12:00:00Z", |
| 149 | + "last_used_at": "2025-08-14T12:30:00Z", |
| 150 | + "created_at": "2025-08-14T12:00:00Z" |
94 | 151 | } |
95 | 152 | ``` |
96 | 153 |
|
97 | | -**Errors**: |
98 | | - |
99 | | -- `401 Unauthorized` → missing, invalid, or expired refresh token |
100 | | - |
101 | | -### 4. Logout |
102 | | - |
103 | | -`POST /auth/logout` |
| 154 | +## **6. Relationships Overview** |
104 | 155 |
|
105 | | -Revokes refresh token (cookie cleared). |
| 156 | +- **Users** have many **Devices**. |
| 157 | +- **Devices** have many **Telemetry entries**. |
| 158 | +- **Devices** can receive many **Commands**. |
| 159 | +- **Users** have many **Tokens**. |
106 | 160 |
|
107 | | -**Response** `204 No Content` |
| 161 | + |
0 commit comments