hazo_chat 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +437 -0
- package/SETUP_CHECKLIST.md +858 -0
- package/dist/components/hazo_chat/hazo_chat.d.ts +16 -0
- package/dist/components/hazo_chat/hazo_chat.d.ts.map +1 -0
- package/dist/components/hazo_chat/hazo_chat.js +155 -0
- package/dist/components/hazo_chat/hazo_chat.js.map +1 -0
- package/dist/components/hazo_chat/hazo_chat_attachment_preview.d.ts +17 -0
- package/dist/components/hazo_chat/hazo_chat_attachment_preview.d.ts.map +1 -0
- package/dist/components/hazo_chat/hazo_chat_attachment_preview.js +60 -0
- package/dist/components/hazo_chat/hazo_chat_attachment_preview.js.map +1 -0
- package/dist/components/hazo_chat/hazo_chat_context.d.ts +36 -0
- package/dist/components/hazo_chat/hazo_chat_context.d.ts.map +1 -0
- package/dist/components/hazo_chat/hazo_chat_context.js +249 -0
- package/dist/components/hazo_chat/hazo_chat_context.js.map +1 -0
- package/dist/components/hazo_chat/hazo_chat_document_viewer.d.ts +15 -0
- package/dist/components/hazo_chat/hazo_chat_document_viewer.d.ts.map +1 -0
- package/dist/components/hazo_chat/hazo_chat_document_viewer.js +111 -0
- package/dist/components/hazo_chat/hazo_chat_document_viewer.js.map +1 -0
- package/dist/components/hazo_chat/hazo_chat_header.d.ts +16 -0
- package/dist/components/hazo_chat/hazo_chat_header.d.ts.map +1 -0
- package/dist/components/hazo_chat/hazo_chat_header.js +24 -0
- package/dist/components/hazo_chat/hazo_chat_header.js.map +1 -0
- package/dist/components/hazo_chat/hazo_chat_input.d.ts +18 -0
- package/dist/components/hazo_chat/hazo_chat_input.d.ts.map +1 -0
- package/dist/components/hazo_chat/hazo_chat_input.js +134 -0
- package/dist/components/hazo_chat/hazo_chat_input.js.map +1 -0
- package/dist/components/hazo_chat/hazo_chat_messages.d.ts +17 -0
- package/dist/components/hazo_chat/hazo_chat_messages.d.ts.map +1 -0
- package/dist/components/hazo_chat/hazo_chat_messages.js +109 -0
- package/dist/components/hazo_chat/hazo_chat_messages.js.map +1 -0
- package/dist/components/hazo_chat/hazo_chat_reference_list.d.ts +16 -0
- package/dist/components/hazo_chat/hazo_chat_reference_list.d.ts.map +1 -0
- package/dist/components/hazo_chat/hazo_chat_reference_list.js +59 -0
- package/dist/components/hazo_chat/hazo_chat_reference_list.js.map +1 -0
- package/dist/components/hazo_chat/hazo_chat_sidebar.d.ts +18 -0
- package/dist/components/hazo_chat/hazo_chat_sidebar.d.ts.map +1 -0
- package/dist/components/hazo_chat/hazo_chat_sidebar.js +72 -0
- package/dist/components/hazo_chat/hazo_chat_sidebar.js.map +1 -0
- package/dist/components/hazo_chat/index.d.ts +16 -0
- package/dist/components/hazo_chat/index.d.ts.map +1 -0
- package/dist/components/hazo_chat/index.js +19 -0
- package/dist/components/hazo_chat/index.js.map +1 -0
- package/dist/components/index.d.ts +9 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +11 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/ui/avatar.d.ts +13 -0
- package/dist/components/ui/avatar.d.ts.map +1 -0
- package/dist/components/ui/avatar.js +28 -0
- package/dist/components/ui/avatar.js.map +1 -0
- package/dist/components/ui/badge.d.ts +16 -0
- package/dist/components/ui/badge.d.ts.map +1 -0
- package/dist/components/ui/badge.js +36 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/button.d.ts +18 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +47 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/chat_bubble.d.ts +19 -0
- package/dist/components/ui/chat_bubble.d.ts.map +1 -0
- package/dist/components/ui/chat_bubble.js +101 -0
- package/dist/components/ui/chat_bubble.js.map +1 -0
- package/dist/components/ui/index.d.ts +18 -0
- package/dist/components/ui/index.d.ts.map +1 -0
- package/dist/components/ui/index.js +20 -0
- package/dist/components/ui/index.js.map +1 -0
- package/dist/components/ui/input.d.ts +11 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/input.js +18 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/loading_skeleton.d.ts +19 -0
- package/dist/components/ui/loading_skeleton.d.ts.map +1 -0
- package/dist/components/ui/loading_skeleton.js +30 -0
- package/dist/components/ui/loading_skeleton.js.map +1 -0
- package/dist/components/ui/scroll-area.d.ts +12 -0
- package/dist/components/ui/scroll-area.d.ts.map +1 -0
- package/dist/components/ui/scroll-area.js +25 -0
- package/dist/components/ui/scroll-area.js.map +1 -0
- package/dist/components/ui/separator.d.ts +11 -0
- package/dist/components/ui/separator.d.ts.map +1 -0
- package/dist/components/ui/separator.js +18 -0
- package/dist/components/ui/separator.js.map +1 -0
- package/dist/components/ui/skeleton.d.ts +9 -0
- package/dist/components/ui/skeleton.d.ts.map +1 -0
- package/dist/components/ui/skeleton.js +16 -0
- package/dist/components/ui/skeleton.js.map +1 -0
- package/dist/components/ui/textarea.d.ts +11 -0
- package/dist/components/ui/textarea.d.ts.map +1 -0
- package/dist/components/ui/textarea.js +18 -0
- package/dist/components/ui/textarea.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +14 -0
- package/dist/components/ui/tooltip.d.ts.map +1 -0
- package/dist/components/ui/tooltip.js +30 -0
- package/dist/components/ui/tooltip.js.map +1 -0
- package/dist/hooks/index.d.ts +10 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +10 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/use_chat_messages.d.ts +25 -0
- package/dist/hooks/use_chat_messages.d.ts.map +1 -0
- package/dist/hooks/use_chat_messages.js +430 -0
- package/dist/hooks/use_chat_messages.js.map +1 -0
- package/dist/hooks/use_chat_references.d.ts +17 -0
- package/dist/hooks/use_chat_references.d.ts.map +1 -0
- package/dist/hooks/use_chat_references.js +133 -0
- package/dist/hooks/use_chat_references.js.map +1 -0
- package/dist/hooks/use_file_upload.d.ts +23 -0
- package/dist/hooks/use_file_upload.d.ts.map +1 -0
- package/dist/hooks/use_file_upload.js +212 -0
- package/dist/hooks/use_file_upload.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +41 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +93 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/constants.d.ts +39 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +70 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/index.d.ts +9 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +9 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/utils.d.ts +17 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +20 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/types/index.d.ts +367 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +93 -0
|
@@ -0,0 +1,858 @@
|
|
|
1
|
+
# hazo_chat Setup Checklist
|
|
2
|
+
|
|
3
|
+
A comprehensive, step-by-step guide for setting up hazo_chat in a Next.js project. This checklist is designed for both AI assistants and human developers.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
1. [Prerequisites](#1-prerequisites)
|
|
10
|
+
2. [Package Installation](#2-package-installation)
|
|
11
|
+
3. [Configuration Files](#3-configuration-files)
|
|
12
|
+
4. [Database Setup](#4-database-setup)
|
|
13
|
+
5. [Environment Variables](#5-environment-variables)
|
|
14
|
+
6. [Next.js Configuration](#6-nextjs-configuration)
|
|
15
|
+
7. [API Routes](#7-api-routes)
|
|
16
|
+
8. [Page Routes (Optional)](#8-page-routes-optional)
|
|
17
|
+
9. [Component Integration](#9-component-integration)
|
|
18
|
+
10. [Verification Checklist](#10-verification-checklist)
|
|
19
|
+
11. [Troubleshooting](#11-troubleshooting)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 1. Prerequisites
|
|
24
|
+
|
|
25
|
+
### Required Software
|
|
26
|
+
- [ ] Node.js >= 18.0.0
|
|
27
|
+
- [ ] npm >= 9.0.0 or yarn >= 1.22.0
|
|
28
|
+
- [ ] Next.js >= 14.0.0 (App Router)
|
|
29
|
+
|
|
30
|
+
### Required Knowledge
|
|
31
|
+
- React and Next.js fundamentals
|
|
32
|
+
- Basic understanding of REST APIs
|
|
33
|
+
- TypeScript basics
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 2. Package Installation
|
|
38
|
+
|
|
39
|
+
### Step 2.1: Install Core Packages
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install hazo_chat hazo_connect hazo_auth hazo_config
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Step 2.2: Install Peer Dependencies (if not already installed)
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm install react react-dom
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Step 2.3: Install Additional Dependencies
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# For UUID generation (optional, if not using hazo_auth's ID generation)
|
|
55
|
+
npm install uuid
|
|
56
|
+
npm install -D @types/uuid
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Verification
|
|
60
|
+
- [ ] `package.json` contains `hazo_chat`, `hazo_connect`, `hazo_auth`
|
|
61
|
+
- [ ] No npm installation errors
|
|
62
|
+
- [ ] `node_modules/hazo_chat` exists
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 3. Configuration Files
|
|
67
|
+
|
|
68
|
+
### Step 3.1: Create hazo_connect_config.ini
|
|
69
|
+
|
|
70
|
+
Create in project root: `hazo_connect_config.ini`
|
|
71
|
+
|
|
72
|
+
```ini
|
|
73
|
+
[database]
|
|
74
|
+
; Database type: sqlite, postgrest, supabase
|
|
75
|
+
type = sqlite
|
|
76
|
+
|
|
77
|
+
; For SQLite - path relative to project root
|
|
78
|
+
sqlite_path = ./data/app.db
|
|
79
|
+
|
|
80
|
+
; For PostgreSQL/Supabase (uncomment if using)
|
|
81
|
+
; postgrest_url = http://localhost:3000
|
|
82
|
+
; supabase_url = https://your-project.supabase.co
|
|
83
|
+
; supabase_anon_key = your-anon-key
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Step 3.2: Create hazo_auth_config.ini
|
|
87
|
+
|
|
88
|
+
Create in project root: `hazo_auth_config.ini`
|
|
89
|
+
|
|
90
|
+
```ini
|
|
91
|
+
[auth]
|
|
92
|
+
; JWT secret for token signing
|
|
93
|
+
jwt_secret = your-secure-secret-key-here
|
|
94
|
+
jwt_expiry = 7d
|
|
95
|
+
|
|
96
|
+
; Cookie settings
|
|
97
|
+
cookie_name = hazo_auth_token
|
|
98
|
+
cookie_secure = false
|
|
99
|
+
cookie_http_only = true
|
|
100
|
+
cookie_same_site = lax
|
|
101
|
+
|
|
102
|
+
[login]
|
|
103
|
+
enable_remember_me = true
|
|
104
|
+
max_login_attempts = 5
|
|
105
|
+
lockout_duration = 300
|
|
106
|
+
|
|
107
|
+
[registration]
|
|
108
|
+
enable_registration = true
|
|
109
|
+
require_email_verification = false
|
|
110
|
+
default_role = user
|
|
111
|
+
|
|
112
|
+
[ui]
|
|
113
|
+
; Visual panel image for auth pages
|
|
114
|
+
visual_panel_image = /globe.svg
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Step 3.3: Create hazo_chat_config.ini (Optional)
|
|
118
|
+
|
|
119
|
+
Create in project root: `hazo_chat_config.ini`
|
|
120
|
+
|
|
121
|
+
```ini
|
|
122
|
+
[chat]
|
|
123
|
+
; Polling interval in milliseconds (default: 5000)
|
|
124
|
+
polling_interval = 5000
|
|
125
|
+
|
|
126
|
+
; Messages to load per page (default: 20)
|
|
127
|
+
messages_per_page = 20
|
|
128
|
+
|
|
129
|
+
[uploads]
|
|
130
|
+
; Maximum file size in MB (default: 10)
|
|
131
|
+
max_file_size_mb = 10
|
|
132
|
+
|
|
133
|
+
; Allowed file extensions
|
|
134
|
+
allowed_types = pdf,png,jpg,jpeg,gif,txt,doc,docx
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Verification
|
|
138
|
+
- [ ] `hazo_connect_config.ini` exists in project root
|
|
139
|
+
- [ ] `hazo_auth_config.ini` exists in project root
|
|
140
|
+
- [ ] Database path directory exists (create `./data/` if using SQLite)
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## 4. Database Setup
|
|
145
|
+
|
|
146
|
+
### Step 4.1: Create hazo_chat Table
|
|
147
|
+
|
|
148
|
+
Run this SQL to create the chat messages table:
|
|
149
|
+
|
|
150
|
+
```sql
|
|
151
|
+
-- hazo_chat table for storing chat messages
|
|
152
|
+
CREATE TABLE IF NOT EXISTS hazo_chat (
|
|
153
|
+
id TEXT PRIMARY KEY,
|
|
154
|
+
reference_id TEXT NOT NULL,
|
|
155
|
+
reference_type TEXT DEFAULT 'chat',
|
|
156
|
+
sender_user_id TEXT NOT NULL,
|
|
157
|
+
receiver_user_id TEXT NOT NULL,
|
|
158
|
+
message_text TEXT,
|
|
159
|
+
reference_list TEXT,
|
|
160
|
+
read_at TEXT,
|
|
161
|
+
deleted_at TEXT,
|
|
162
|
+
created_at TEXT NOT NULL,
|
|
163
|
+
changed_at TEXT NOT NULL
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
-- Performance indexes
|
|
167
|
+
CREATE INDEX IF NOT EXISTS idx_hazo_chat_reference_id ON hazo_chat(reference_id);
|
|
168
|
+
CREATE INDEX IF NOT EXISTS idx_hazo_chat_sender ON hazo_chat(sender_user_id);
|
|
169
|
+
CREATE INDEX IF NOT EXISTS idx_hazo_chat_receiver ON hazo_chat(receiver_user_id);
|
|
170
|
+
CREATE INDEX IF NOT EXISTS idx_hazo_chat_created ON hazo_chat(created_at DESC);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Step 4.2: Ensure hazo_users Table Exists
|
|
174
|
+
|
|
175
|
+
hazo_auth should have created this, but verify:
|
|
176
|
+
|
|
177
|
+
```sql
|
|
178
|
+
-- hazo_users table (created by hazo_auth)
|
|
179
|
+
CREATE TABLE IF NOT EXISTS hazo_users (
|
|
180
|
+
id TEXT PRIMARY KEY,
|
|
181
|
+
email_address TEXT UNIQUE NOT NULL,
|
|
182
|
+
password_hash TEXT NOT NULL,
|
|
183
|
+
name TEXT,
|
|
184
|
+
profile_picture_url TEXT,
|
|
185
|
+
profile_source TEXT DEFAULT 'default',
|
|
186
|
+
is_active INTEGER DEFAULT 1,
|
|
187
|
+
email_verified INTEGER DEFAULT 0,
|
|
188
|
+
created_at TEXT NOT NULL,
|
|
189
|
+
changed_at TEXT NOT NULL
|
|
190
|
+
);
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Verification
|
|
194
|
+
- [ ] `hazo_chat` table exists in database
|
|
195
|
+
- [ ] `hazo_users` table exists with at least one user
|
|
196
|
+
- [ ] Can query: `SELECT * FROM hazo_chat LIMIT 1`
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## 5. Environment Variables
|
|
201
|
+
|
|
202
|
+
### Step 5.1: Create .env.local
|
|
203
|
+
|
|
204
|
+
```env
|
|
205
|
+
# Database (if not using config.ini)
|
|
206
|
+
HAZO_CONNECT_TYPE=sqlite
|
|
207
|
+
HAZO_CONNECT_SQLITE_PATH=./data/app.db
|
|
208
|
+
|
|
209
|
+
# Auth secrets
|
|
210
|
+
HAZO_AUTH_JWT_SECRET=your-secure-secret-key-min-32-chars
|
|
211
|
+
|
|
212
|
+
# Optional: Supabase/PostgreSQL
|
|
213
|
+
# HAZO_CONNECT_POSTGREST_URL=http://localhost:3000
|
|
214
|
+
# SUPABASE_URL=https://your-project.supabase.co
|
|
215
|
+
# SUPABASE_ANON_KEY=your-anon-key
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Step 5.2: Add to .gitignore
|
|
219
|
+
|
|
220
|
+
```gitignore
|
|
221
|
+
# Environment files
|
|
222
|
+
.env
|
|
223
|
+
.env.local
|
|
224
|
+
.env.*.local
|
|
225
|
+
|
|
226
|
+
# Database files (if using SQLite)
|
|
227
|
+
*.db
|
|
228
|
+
*.sqlite
|
|
229
|
+
data/
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Verification
|
|
233
|
+
- [ ] `.env.local` exists
|
|
234
|
+
- [ ] `.env.local` is in `.gitignore`
|
|
235
|
+
- [ ] Secrets are not committed to git
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## 6. Next.js Configuration
|
|
240
|
+
|
|
241
|
+
### Step 6.1: Update next.config.js
|
|
242
|
+
|
|
243
|
+
```javascript
|
|
244
|
+
/**
|
|
245
|
+
* Next.js Configuration with hazo_chat support
|
|
246
|
+
*/
|
|
247
|
+
|
|
248
|
+
const path = require('path');
|
|
249
|
+
|
|
250
|
+
/** @type {import('next').NextConfig} */
|
|
251
|
+
const nextConfig = {
|
|
252
|
+
// Transpile the hazo packages for ES module support
|
|
253
|
+
transpilePackages: ['hazo_chat', 'hazo_connect', 'hazo_auth'],
|
|
254
|
+
|
|
255
|
+
// Webpack configuration
|
|
256
|
+
webpack: (config, { isServer }) => {
|
|
257
|
+
// Configure module resolution
|
|
258
|
+
config.resolve.extensionAlias = {
|
|
259
|
+
'.js': ['.js', '.ts', '.tsx'],
|
|
260
|
+
'.jsx': ['.jsx', '.tsx'],
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
// Enable package exports resolution
|
|
264
|
+
config.resolve.conditionNames = ['import', 'require', 'default'];
|
|
265
|
+
|
|
266
|
+
// Server-side externals
|
|
267
|
+
if (isServer) {
|
|
268
|
+
config.externals = config.externals || [];
|
|
269
|
+
if (Array.isArray(config.externals)) {
|
|
270
|
+
config.externals.push("sql.js");
|
|
271
|
+
config.externals.push("hazo_notify");
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// WebAssembly support for sql.js
|
|
276
|
+
config.experiments = {
|
|
277
|
+
...(config.experiments ?? {}),
|
|
278
|
+
asyncWebAssembly: true,
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
return config;
|
|
282
|
+
},
|
|
283
|
+
|
|
284
|
+
// Experimental features
|
|
285
|
+
experimental: {
|
|
286
|
+
serverComponentsExternalPackages: [
|
|
287
|
+
"sql.js",
|
|
288
|
+
"better-sqlite3",
|
|
289
|
+
"hazo_notify",
|
|
290
|
+
],
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
module.exports = nextConfig;
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### Verification
|
|
298
|
+
- [ ] `next.config.js` includes transpilePackages
|
|
299
|
+
- [ ] Server externals configured for sql.js
|
|
300
|
+
- [ ] No build errors with `npm run build`
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## 7. API Routes
|
|
305
|
+
|
|
306
|
+
Create the following API routes in `src/app/api/`:
|
|
307
|
+
|
|
308
|
+
### Step 7.1: Chat Messages API
|
|
309
|
+
|
|
310
|
+
**File: `src/app/api/hazo_chat/messages/route.ts`**
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
/**
|
|
314
|
+
* API route for chat message operations
|
|
315
|
+
*/
|
|
316
|
+
|
|
317
|
+
export const dynamic = "force-dynamic";
|
|
318
|
+
|
|
319
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
320
|
+
import { cookies } from "next/headers";
|
|
321
|
+
import { createCrudService } from "hazo_connect/server";
|
|
322
|
+
import { getHazoConnectSingleton } from "hazo_connect/nextjs/setup";
|
|
323
|
+
import { v4 as uuid_v4 } from "uuid";
|
|
324
|
+
|
|
325
|
+
interface ChatMessageDB {
|
|
326
|
+
id: string;
|
|
327
|
+
reference_id: string;
|
|
328
|
+
reference_type: string;
|
|
329
|
+
sender_user_id: string;
|
|
330
|
+
receiver_user_id: string;
|
|
331
|
+
message_text: string | null;
|
|
332
|
+
reference_list: string | null;
|
|
333
|
+
read_at: string | null;
|
|
334
|
+
deleted_at: string | null;
|
|
335
|
+
created_at: string;
|
|
336
|
+
changed_at: string;
|
|
337
|
+
[key: string]: unknown;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// GET - Fetch messages
|
|
341
|
+
export async function GET(request: NextRequest) {
|
|
342
|
+
try {
|
|
343
|
+
const cookieStore = cookies();
|
|
344
|
+
const current_user_id = cookieStore.get("hazo_auth_user_id")?.value;
|
|
345
|
+
|
|
346
|
+
if (!current_user_id) {
|
|
347
|
+
return NextResponse.json(
|
|
348
|
+
{ success: false, error: "Not authenticated" },
|
|
349
|
+
{ status: 401 }
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const { searchParams } = new URL(request.url);
|
|
354
|
+
const receiver_user_id = searchParams.get("receiver_user_id");
|
|
355
|
+
const reference_id = searchParams.get("reference_id");
|
|
356
|
+
const reference_type = searchParams.get("reference_type");
|
|
357
|
+
|
|
358
|
+
if (!receiver_user_id) {
|
|
359
|
+
return NextResponse.json(
|
|
360
|
+
{ success: false, error: "receiver_user_id is required" },
|
|
361
|
+
{ status: 400 }
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const hazoConnect = getHazoConnectSingleton();
|
|
366
|
+
const chatService = createCrudService<ChatMessageDB>(hazoConnect, "hazo_chat");
|
|
367
|
+
|
|
368
|
+
const messages = await chatService.list((query) => {
|
|
369
|
+
let filteredQuery = query.whereOr([
|
|
370
|
+
{ field: "sender_user_id", operator: "eq", value: current_user_id },
|
|
371
|
+
{ field: "receiver_user_id", operator: "eq", value: current_user_id },
|
|
372
|
+
]);
|
|
373
|
+
|
|
374
|
+
if (reference_id) {
|
|
375
|
+
filteredQuery = filteredQuery.where("reference_id", "eq", reference_id);
|
|
376
|
+
}
|
|
377
|
+
if (reference_type) {
|
|
378
|
+
filteredQuery = filteredQuery.where("reference_type", "eq", reference_type);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return filteredQuery.order("created_at", "asc");
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
return NextResponse.json({
|
|
385
|
+
success: true,
|
|
386
|
+
messages: messages || [],
|
|
387
|
+
current_user_id,
|
|
388
|
+
});
|
|
389
|
+
} catch (error) {
|
|
390
|
+
console.error("[hazo_chat/messages GET] Error:", error);
|
|
391
|
+
return NextResponse.json(
|
|
392
|
+
{ success: false, error: "Failed to fetch messages" },
|
|
393
|
+
{ status: 500 }
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// POST - Create message
|
|
399
|
+
export async function POST(request: NextRequest) {
|
|
400
|
+
try {
|
|
401
|
+
const cookieStore = cookies();
|
|
402
|
+
const sender_user_id = cookieStore.get("hazo_auth_user_id")?.value;
|
|
403
|
+
|
|
404
|
+
if (!sender_user_id) {
|
|
405
|
+
return NextResponse.json(
|
|
406
|
+
{ success: false, error: "Not authenticated" },
|
|
407
|
+
{ status: 401 }
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const body = await request.json();
|
|
412
|
+
const { receiver_user_id, message_text, reference_id, reference_type, reference_list } = body;
|
|
413
|
+
|
|
414
|
+
if (!receiver_user_id || !message_text?.trim()) {
|
|
415
|
+
return NextResponse.json(
|
|
416
|
+
{ success: false, error: "receiver_user_id and message_text are required" },
|
|
417
|
+
{ status: 400 }
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
const hazoConnect = getHazoConnectSingleton();
|
|
422
|
+
const chatService = createCrudService<ChatMessageDB>(hazoConnect, "hazo_chat");
|
|
423
|
+
|
|
424
|
+
const message_id = uuid_v4();
|
|
425
|
+
const now = new Date().toISOString();
|
|
426
|
+
|
|
427
|
+
const message_record: ChatMessageDB = {
|
|
428
|
+
id: message_id,
|
|
429
|
+
reference_id: reference_id || message_id,
|
|
430
|
+
reference_type: reference_type || "chat",
|
|
431
|
+
sender_user_id,
|
|
432
|
+
receiver_user_id,
|
|
433
|
+
message_text: message_text.trim(),
|
|
434
|
+
reference_list: reference_list ? JSON.stringify(reference_list) : null,
|
|
435
|
+
read_at: null,
|
|
436
|
+
deleted_at: null,
|
|
437
|
+
created_at: now,
|
|
438
|
+
changed_at: now,
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
await chatService.insert(message_record);
|
|
442
|
+
|
|
443
|
+
return NextResponse.json({
|
|
444
|
+
success: true,
|
|
445
|
+
message: message_record,
|
|
446
|
+
});
|
|
447
|
+
} catch (error) {
|
|
448
|
+
console.error("[hazo_chat/messages POST] Error:", error);
|
|
449
|
+
return NextResponse.json(
|
|
450
|
+
{ success: false, error: "Failed to send message" },
|
|
451
|
+
{ status: 500 }
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### Step 7.2: Auth Me API
|
|
458
|
+
|
|
459
|
+
**File: `src/app/api/hazo_auth/me/route.ts`**
|
|
460
|
+
|
|
461
|
+
```typescript
|
|
462
|
+
/**
|
|
463
|
+
* API route to get current authenticated user
|
|
464
|
+
*/
|
|
465
|
+
|
|
466
|
+
export const dynamic = "force-dynamic";
|
|
467
|
+
|
|
468
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
469
|
+
import { hazo_get_auth } from "hazo_auth/lib/auth/hazo_get_auth.server";
|
|
470
|
+
|
|
471
|
+
export async function GET(request: NextRequest) {
|
|
472
|
+
try {
|
|
473
|
+
const auth_result = await hazo_get_auth(request);
|
|
474
|
+
|
|
475
|
+
if (!auth_result.is_authenticated || !auth_result.user) {
|
|
476
|
+
return NextResponse.json({
|
|
477
|
+
is_authenticated: false,
|
|
478
|
+
user_id: null,
|
|
479
|
+
email: null,
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
return NextResponse.json({
|
|
484
|
+
is_authenticated: true,
|
|
485
|
+
user_id: auth_result.user.id,
|
|
486
|
+
email: auth_result.user.email_address,
|
|
487
|
+
name: auth_result.user.name,
|
|
488
|
+
profile_picture_url: auth_result.user.profile_picture_url,
|
|
489
|
+
});
|
|
490
|
+
} catch (error) {
|
|
491
|
+
console.error("[hazo_auth/me] Error:", error);
|
|
492
|
+
return NextResponse.json({
|
|
493
|
+
is_authenticated: false,
|
|
494
|
+
user_id: null,
|
|
495
|
+
email: null,
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
### Step 7.3: User Profiles API
|
|
502
|
+
|
|
503
|
+
**File: `src/app/api/hazo_auth/profiles/route.ts`**
|
|
504
|
+
|
|
505
|
+
```typescript
|
|
506
|
+
/**
|
|
507
|
+
* API route to fetch user profiles by IDs
|
|
508
|
+
*/
|
|
509
|
+
|
|
510
|
+
export const dynamic = "force-dynamic";
|
|
511
|
+
|
|
512
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
513
|
+
import { createCrudService } from "hazo_connect/server";
|
|
514
|
+
import { getHazoConnectSingleton } from "hazo_connect/nextjs/setup";
|
|
515
|
+
|
|
516
|
+
interface UserProfile {
|
|
517
|
+
id: string;
|
|
518
|
+
name: string;
|
|
519
|
+
email: string;
|
|
520
|
+
avatar_url?: string;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
export async function POST(request: NextRequest) {
|
|
524
|
+
try {
|
|
525
|
+
const body = await request.json();
|
|
526
|
+
const { user_ids } = body;
|
|
527
|
+
|
|
528
|
+
if (!Array.isArray(user_ids) || user_ids.length === 0) {
|
|
529
|
+
return NextResponse.json(
|
|
530
|
+
{ success: false, error: "user_ids array is required" },
|
|
531
|
+
{ status: 400 }
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
const hazoConnect = getHazoConnectSingleton();
|
|
536
|
+
const usersService = createCrudService(hazoConnect, "hazo_users");
|
|
537
|
+
|
|
538
|
+
const users = await usersService.list((query) =>
|
|
539
|
+
query.whereIn("id", user_ids)
|
|
540
|
+
);
|
|
541
|
+
|
|
542
|
+
const profiles: UserProfile[] = users.map((user) => ({
|
|
543
|
+
id: user.id as string,
|
|
544
|
+
name: (user.name as string) || (user.email_address as string).split("@")[0],
|
|
545
|
+
email: user.email_address as string,
|
|
546
|
+
avatar_url: user.profile_picture_url as string | undefined,
|
|
547
|
+
}));
|
|
548
|
+
|
|
549
|
+
return NextResponse.json({ success: true, profiles });
|
|
550
|
+
} catch (error) {
|
|
551
|
+
console.error("[hazo_auth/profiles] Error:", error);
|
|
552
|
+
return NextResponse.json(
|
|
553
|
+
{ success: false, error: "Failed to fetch profiles" },
|
|
554
|
+
{ status: 500 }
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
### Step 7.4: Additional Auth API Routes (Required for full hazo_auth)
|
|
561
|
+
|
|
562
|
+
Create these additional routes if using hazo_auth authentication pages:
|
|
563
|
+
|
|
564
|
+
| Route | File Path | Purpose |
|
|
565
|
+
|-------|-----------|---------|
|
|
566
|
+
| Login | `api/hazo_auth/login/route.ts` | User login |
|
|
567
|
+
| Logout | `api/hazo_auth/logout/route.ts` | User logout |
|
|
568
|
+
| Register | `api/hazo_auth/register/route.ts` | User registration |
|
|
569
|
+
| Users List | `api/hazo_auth/users/route.ts` | List all users |
|
|
570
|
+
|
|
571
|
+
See the test-app in this repository for complete implementations.
|
|
572
|
+
|
|
573
|
+
### Verification Checklist
|
|
574
|
+
- [ ] `api/hazo_chat/messages/route.ts` exists
|
|
575
|
+
- [ ] `api/hazo_auth/me/route.ts` exists
|
|
576
|
+
- [ ] `api/hazo_auth/profiles/route.ts` exists
|
|
577
|
+
- [ ] API routes return 200 when tested with curl
|
|
578
|
+
|
|
579
|
+
---
|
|
580
|
+
|
|
581
|
+
## 8. Page Routes (Optional)
|
|
582
|
+
|
|
583
|
+
If using hazo_auth authentication pages, create these routes:
|
|
584
|
+
|
|
585
|
+
### Authentication Pages
|
|
586
|
+
|
|
587
|
+
| Page | File Path | Purpose |
|
|
588
|
+
|------|-----------|---------|
|
|
589
|
+
| Login | `app/hazo_auth/login/page.tsx` | Login page |
|
|
590
|
+
| Register | `app/hazo_auth/register/page.tsx` | Registration page |
|
|
591
|
+
| Forgot Password | `app/hazo_auth/forgot_password/page.tsx` | Password reset request |
|
|
592
|
+
| Reset Password | `app/hazo_auth/reset_password/page.tsx` | Password reset form |
|
|
593
|
+
| Verify Email | `app/hazo_auth/verify_email/page.tsx` | Email verification |
|
|
594
|
+
| My Settings | `app/hazo_auth/my_settings/page.tsx` | User settings |
|
|
595
|
+
|
|
596
|
+
See the test-app for complete page implementations.
|
|
597
|
+
|
|
598
|
+
---
|
|
599
|
+
|
|
600
|
+
## 9. Component Integration
|
|
601
|
+
|
|
602
|
+
### Step 9.1: Create hazo_auth Service Wrapper
|
|
603
|
+
|
|
604
|
+
**File: `src/lib/hazo_auth_client.ts`**
|
|
605
|
+
|
|
606
|
+
```typescript
|
|
607
|
+
/**
|
|
608
|
+
* Client-side hazo_auth service wrapper
|
|
609
|
+
*/
|
|
610
|
+
|
|
611
|
+
import type { HazoAuthInstance, HazoUserProfile } from 'hazo_chat';
|
|
612
|
+
|
|
613
|
+
export const hazo_auth_client: HazoAuthInstance = {
|
|
614
|
+
hazo_get_auth: async () => {
|
|
615
|
+
try {
|
|
616
|
+
const response = await fetch('/api/hazo_auth/me');
|
|
617
|
+
const data = await response.json();
|
|
618
|
+
|
|
619
|
+
if (data.is_authenticated) {
|
|
620
|
+
return {
|
|
621
|
+
id: data.user_id,
|
|
622
|
+
email: data.email,
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
return null;
|
|
626
|
+
} catch (error) {
|
|
627
|
+
console.error('Failed to get auth:', error);
|
|
628
|
+
return null;
|
|
629
|
+
}
|
|
630
|
+
},
|
|
631
|
+
|
|
632
|
+
hazo_get_user_profiles: async (user_ids: string[]): Promise<HazoUserProfile[]> => {
|
|
633
|
+
try {
|
|
634
|
+
const response = await fetch('/api/hazo_auth/profiles', {
|
|
635
|
+
method: 'POST',
|
|
636
|
+
headers: { 'Content-Type': 'application/json' },
|
|
637
|
+
body: JSON.stringify({ user_ids }),
|
|
638
|
+
});
|
|
639
|
+
const data = await response.json();
|
|
640
|
+
|
|
641
|
+
if (data.success) {
|
|
642
|
+
return data.profiles;
|
|
643
|
+
}
|
|
644
|
+
return [];
|
|
645
|
+
} catch (error) {
|
|
646
|
+
console.error('Failed to get profiles:', error);
|
|
647
|
+
return [];
|
|
648
|
+
}
|
|
649
|
+
},
|
|
650
|
+
};
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
### Step 9.2: Integrate HazoChat Component
|
|
654
|
+
|
|
655
|
+
**File: `src/app/chat/page.tsx`**
|
|
656
|
+
|
|
657
|
+
```typescript
|
|
658
|
+
'use client';
|
|
659
|
+
|
|
660
|
+
import { useState, useEffect } from 'react';
|
|
661
|
+
import { useRouter } from 'next/navigation';
|
|
662
|
+
import { HazoChat } from 'hazo_chat';
|
|
663
|
+
import { getHazoConnectSingleton } from 'hazo_connect/nextjs/setup';
|
|
664
|
+
import { hazo_auth_client } from '@/lib/hazo_auth_client';
|
|
665
|
+
|
|
666
|
+
export default function ChatPage() {
|
|
667
|
+
const router = useRouter();
|
|
668
|
+
const [is_authenticated, set_is_authenticated] = useState(false);
|
|
669
|
+
const [is_loading, set_is_loading] = useState(true);
|
|
670
|
+
const [recipient_id, set_recipient_id] = useState<string>('');
|
|
671
|
+
|
|
672
|
+
// Check authentication on mount
|
|
673
|
+
useEffect(() => {
|
|
674
|
+
async function check_auth() {
|
|
675
|
+
const user = await hazo_auth_client.hazo_get_auth();
|
|
676
|
+
if (!user) {
|
|
677
|
+
router.push('/hazo_auth/login');
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
set_is_authenticated(true);
|
|
681
|
+
set_is_loading(false);
|
|
682
|
+
}
|
|
683
|
+
check_auth();
|
|
684
|
+
}, [router]);
|
|
685
|
+
|
|
686
|
+
if (is_loading) {
|
|
687
|
+
return <div>Loading...</div>;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
if (!is_authenticated || !recipient_id) {
|
|
691
|
+
return <div>Select a user to chat with</div>;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
const hazo_connect = getHazoConnectSingleton();
|
|
695
|
+
|
|
696
|
+
return (
|
|
697
|
+
<div className="h-screen">
|
|
698
|
+
<HazoChat
|
|
699
|
+
hazo_connect={hazo_connect}
|
|
700
|
+
hazo_auth={hazo_auth_client}
|
|
701
|
+
receiver_user_id={recipient_id}
|
|
702
|
+
document_save_location="/uploads/chat"
|
|
703
|
+
reference_id={`chat-${recipient_id}`}
|
|
704
|
+
reference_type="direct_message"
|
|
705
|
+
title="Chat"
|
|
706
|
+
on_close={() => router.back()}
|
|
707
|
+
/>
|
|
708
|
+
</div>
|
|
709
|
+
);
|
|
710
|
+
}
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
---
|
|
714
|
+
|
|
715
|
+
## 10. Verification Checklist
|
|
716
|
+
|
|
717
|
+
### Installation Verification
|
|
718
|
+
- [ ] All packages installed without errors
|
|
719
|
+
- [ ] `npm run build` completes successfully
|
|
720
|
+
- [ ] No TypeScript errors
|
|
721
|
+
|
|
722
|
+
### Configuration Verification
|
|
723
|
+
- [ ] `hazo_connect_config.ini` exists and is readable
|
|
724
|
+
- [ ] Database file/connection is accessible
|
|
725
|
+
- [ ] Environment variables are set
|
|
726
|
+
|
|
727
|
+
### Database Verification
|
|
728
|
+
- [ ] `hazo_chat` table exists
|
|
729
|
+
- [ ] `hazo_users` table exists with test users
|
|
730
|
+
- [ ] Can insert and query messages
|
|
731
|
+
|
|
732
|
+
### API Verification
|
|
733
|
+
|
|
734
|
+
Test with curl or browser:
|
|
735
|
+
|
|
736
|
+
```bash
|
|
737
|
+
# Test auth endpoint
|
|
738
|
+
curl http://localhost:3000/api/hazo_auth/me
|
|
739
|
+
|
|
740
|
+
# Test profiles endpoint (with cookie/auth)
|
|
741
|
+
curl -X POST http://localhost:3000/api/hazo_auth/profiles \
|
|
742
|
+
-H "Content-Type: application/json" \
|
|
743
|
+
-d '{"user_ids": ["user-id-here"]}'
|
|
744
|
+
|
|
745
|
+
# Test messages endpoint (with cookie/auth)
|
|
746
|
+
curl "http://localhost:3000/api/hazo_chat/messages?receiver_user_id=user-id"
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
Expected responses:
|
|
750
|
+
- [ ] `/api/hazo_auth/me` returns user data or `is_authenticated: false`
|
|
751
|
+
- [ ] `/api/hazo_auth/profiles` returns user profiles array
|
|
752
|
+
- [ ] `/api/hazo_chat/messages` returns messages array
|
|
753
|
+
|
|
754
|
+
### UI Verification
|
|
755
|
+
- [ ] Chat component renders without errors
|
|
756
|
+
- [ ] Messages load and display correctly
|
|
757
|
+
- [ ] Can send new messages
|
|
758
|
+
- [ ] Messages appear in real-time (within polling interval)
|
|
759
|
+
- [ ] File upload works (if configured)
|
|
760
|
+
|
|
761
|
+
---
|
|
762
|
+
|
|
763
|
+
## 11. Troubleshooting
|
|
764
|
+
|
|
765
|
+
### Error: "hazo_connect.from is not a function"
|
|
766
|
+
|
|
767
|
+
**Cause:** Using wrong adapter type or import.
|
|
768
|
+
|
|
769
|
+
**Solution:**
|
|
770
|
+
```typescript
|
|
771
|
+
// Wrong
|
|
772
|
+
import hazo_connect from 'hazo_connect';
|
|
773
|
+
|
|
774
|
+
// Correct
|
|
775
|
+
import { getHazoConnectSingleton } from 'hazo_connect/nextjs/setup';
|
|
776
|
+
const hazo_connect = getHazoConnectSingleton();
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
### Error: "Module not found"
|
|
780
|
+
|
|
781
|
+
**Cause:** Package not transpiled by Next.js.
|
|
782
|
+
|
|
783
|
+
**Solution:** Add to `next.config.js`:
|
|
784
|
+
```javascript
|
|
785
|
+
transpilePackages: ['hazo_chat', 'hazo_connect', 'hazo_auth'],
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
### Error: "Hydration failed"
|
|
789
|
+
|
|
790
|
+
**Cause:** Server/client rendering mismatch.
|
|
791
|
+
|
|
792
|
+
**Solution:**
|
|
793
|
+
```typescript
|
|
794
|
+
const [mounted, set_mounted] = useState(false);
|
|
795
|
+
useEffect(() => set_mounted(true), []);
|
|
796
|
+
if (!mounted) return null;
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
### Error: "Database not found"
|
|
800
|
+
|
|
801
|
+
**Cause:** SQLite path incorrect or directory doesn't exist.
|
|
802
|
+
|
|
803
|
+
**Solution:**
|
|
804
|
+
1. Create data directory: `mkdir -p ./data`
|
|
805
|
+
2. Check path in `hazo_connect_config.ini`
|
|
806
|
+
3. Ensure path is relative to project root
|
|
807
|
+
|
|
808
|
+
### Messages Not Loading
|
|
809
|
+
|
|
810
|
+
**Checklist:**
|
|
811
|
+
1. Is user authenticated? Check `/api/hazo_auth/me`
|
|
812
|
+
2. Is `reference_id` provided to HazoChat?
|
|
813
|
+
3. Is database accessible?
|
|
814
|
+
4. Check browser console for errors
|
|
815
|
+
5. Check server logs for API errors
|
|
816
|
+
|
|
817
|
+
### Polling Not Working
|
|
818
|
+
|
|
819
|
+
**Checklist:**
|
|
820
|
+
1. Check network tab for `/api/hazo_chat/messages` requests
|
|
821
|
+
2. Verify `polling_interval` in config (default: 5000ms)
|
|
822
|
+
3. Check for JavaScript errors in console
|
|
823
|
+
|
|
824
|
+
---
|
|
825
|
+
|
|
826
|
+
## Quick Setup Summary
|
|
827
|
+
|
|
828
|
+
```bash
|
|
829
|
+
# 1. Install packages
|
|
830
|
+
npm install hazo_chat hazo_connect hazo_auth hazo_config uuid
|
|
831
|
+
|
|
832
|
+
# 2. Create config files
|
|
833
|
+
touch hazo_connect_config.ini hazo_auth_config.ini
|
|
834
|
+
|
|
835
|
+
# 3. Create database directory
|
|
836
|
+
mkdir -p ./data
|
|
837
|
+
|
|
838
|
+
# 4. Create API routes
|
|
839
|
+
mkdir -p src/app/api/hazo_chat/messages
|
|
840
|
+
mkdir -p src/app/api/hazo_auth/me
|
|
841
|
+
mkdir -p src/app/api/hazo_auth/profiles
|
|
842
|
+
|
|
843
|
+
# 5. Update next.config.js with transpilePackages
|
|
844
|
+
|
|
845
|
+
# 6. Run database migrations (create hazo_chat table)
|
|
846
|
+
|
|
847
|
+
# 7. Start development server
|
|
848
|
+
npm run dev
|
|
849
|
+
|
|
850
|
+
# 8. Test API endpoints
|
|
851
|
+
|
|
852
|
+
# 9. Integrate HazoChat component
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
---
|
|
856
|
+
|
|
857
|
+
For more information, see the [README.md](./README.md) and [test-app](./test-app) for complete working examples.
|
|
858
|
+
|