File size: 8,256 Bytes
851cd13
 
 
 
 
 
 
 
a758b0c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2860609
 
bcd0eb8
b7a94e7
 
2860609
 
 
 
 
 
 
 
bcd0eb8
2860609
 
bcd0eb8
 
 
 
 
2860609
 
 
 
 
 
 
df9de2d
2860609
 
 
 
 
 
 
 
 
 
 
 
 
 
a758b0c
851cd13
 
a758b0c
 
 
 
 
 
 
2860609
 
 
 
 
 
 
 
df9de2d
2860609
 
 
 
851cd13
 
 
a758b0c
 
2860609
 
 
851cd13
a758b0c
851cd13
 
 
a758b0c
 
 
 
 
 
2860609
 
 
 
 
 
 
bcd0eb8
 
851cd13
 
 
 
 
 
 
 
 
a758b0c
851cd13
 
 
a758b0c
 
 
 
 
 
 
 
 
 
 
 
 
 
bcd0eb8
 
2860609
 
 
 
 
 
 
 
 
bcd0eb8
2860609
 
 
 
 
 
 
 
 
df9de2d
2860609
 
 
 
 
df9de2d
2860609
 
 
 
 
 
 
 
 
 
 
 
 
 
df9de2d
2860609
 
 
 
 
 
 
 
 
 
 
 
 
 
df9de2d
2860609
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
-- Create users table for WhatsApp AI Agent
CREATE TABLE IF NOT EXISTS users (
    wa_id TEXT PRIMARY KEY,
    name TEXT NOT NULL DEFAULT 'Unknown',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Create chat_sessions table
CREATE TABLE IF NOT EXISTS chat_sessions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    wa_id TEXT NOT NULL REFERENCES users(wa_id) ON DELETE CASCADE,
    started_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    last_activity TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    ended BOOLEAN DEFAULT FALSE
);

-- Create messages table
CREATE TABLE IF NOT EXISTS messages (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    session_id UUID NOT NULL REFERENCES chat_sessions(id) ON DELETE CASCADE,
    wa_id TEXT NOT NULL REFERENCES users(wa_id) ON DELETE CASCADE,
    wamid TEXT NOT NULL, -- Meta message ID
    role TEXT NOT NULL CHECK (role IN ('user', 'assistant')),
    content TEXT NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Create user_personas table for user preferences and context
CREATE TABLE IF NOT EXISTS user_personas (
    wa_id TEXT PRIMARY KEY REFERENCES users(wa_id) ON DELETE CASCADE,
    language TEXT,
    tone TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Create user_intents table for session-specific property search intent
CREATE TABLE IF NOT EXISTS user_intents (
    session_id UUID PRIMARY KEY REFERENCES chat_sessions(id) ON DELETE CASCADE,
    wa_id TEXT NOT NULL REFERENCES users(wa_id) ON DELETE CASCADE,
    location_preference TEXT,
    budget INTEGER,
    size_preference_sqm INTEGER,
    must_have TEXT[],
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Create properties table for property listings
CREATE TABLE IF NOT EXISTS properties (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    title TEXT NOT NULL,
    description TEXT,
    location TEXT NOT NULL,
    city TEXT NOT NULL,
    address TEXT,
    size_sqm INTEGER,
    price INTEGER,
    price_type TEXT DEFAULT 'monthly',
    listing_url TEXT,
    images TEXT[],
    features TEXT[],
    floorplan_pdf TEXT,
    video_url TEXT,
    is_active BOOLEAN DEFAULT TRUE,
    is_featured BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Create indexes for better query performance
CREATE INDEX IF NOT EXISTS idx_users_created_at ON users(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_users_updated_at ON users(updated_at DESC);
CREATE INDEX IF NOT EXISTS idx_chat_sessions_wa_id ON chat_sessions(wa_id);
CREATE INDEX IF NOT EXISTS idx_chat_sessions_last_activity ON chat_sessions(last_activity DESC);
CREATE INDEX IF NOT EXISTS idx_chat_sessions_ended ON chat_sessions(ended);
CREATE INDEX IF NOT EXISTS idx_messages_session_id ON messages(session_id);
CREATE INDEX IF NOT EXISTS idx_messages_wa_id ON messages(wa_id);
CREATE INDEX IF NOT EXISTS idx_messages_created_at ON messages(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_messages_wamid ON messages(wamid);
CREATE INDEX IF NOT EXISTS idx_user_personas_wa_id ON user_personas(wa_id);
CREATE INDEX IF NOT EXISTS idx_user_personas_updated_at ON user_personas(updated_at DESC);
CREATE INDEX IF NOT EXISTS idx_user_intents_session_id ON user_intents(session_id);
CREATE INDEX IF NOT EXISTS idx_user_intents_wa_id ON user_intents(wa_id);
CREATE INDEX IF NOT EXISTS idx_user_intents_updated_at ON user_intents(updated_at DESC);
CREATE INDEX IF NOT EXISTS idx_properties_is_active ON properties(is_active);
CREATE INDEX IF NOT EXISTS idx_properties_city ON properties(city);
CREATE INDEX IF NOT EXISTS idx_properties_location ON properties(location);
CREATE INDEX IF NOT EXISTS idx_properties_address ON properties(address);
CREATE INDEX IF NOT EXISTS idx_properties_price ON properties(price);
CREATE INDEX IF NOT EXISTS idx_properties_size_sqm ON properties(size_sqm);
CREATE INDEX IF NOT EXISTS idx_properties_is_featured ON properties(is_featured);
CREATE INDEX IF NOT EXISTS idx_properties_created_at ON properties(created_at DESC);

-- Enable Row Level Security (RLS) - optional but recommended
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
ALTER TABLE chat_sessions ENABLE ROW LEVEL SECURITY;
ALTER TABLE messages ENABLE ROW LEVEL SECURITY;
ALTER TABLE user_personas ENABLE ROW LEVEL SECURITY;
ALTER TABLE user_intents ENABLE ROW LEVEL SECURITY;
ALTER TABLE properties ENABLE ROW LEVEL SECURITY;

-- Create policies to allow all operations (you can restrict this based on your needs)
CREATE POLICY "Allow all operations on users" ON users
    FOR ALL USING (true);

CREATE POLICY "Allow all operations on chat_sessions" ON chat_sessions
    FOR ALL USING (true);

CREATE POLICY "Allow all operations on messages" ON messages
    FOR ALL USING (true);

CREATE POLICY "Allow all operations on user_personas" ON user_personas
    FOR ALL USING (true);

CREATE POLICY "Allow all operations on user_intents" ON user_intents
    FOR ALL USING (true);

CREATE POLICY "Allow all operations on properties" ON properties
    FOR ALL USING (true);

-- Optional: Create a function to automatically update the updated_at timestamp
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ language 'plpgsql';

-- Create trigger to automatically update updated_at for users
CREATE TRIGGER update_users_updated_at 
    BEFORE UPDATE ON users 
    FOR EACH ROW 
    EXECUTE FUNCTION update_updated_at_column();

-- Create trigger to automatically update last_activity for chat_sessions
CREATE OR REPLACE FUNCTION update_last_activity_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.last_activity = NOW();
    RETURN NEW;
END;
$$ language 'plpgsql';

CREATE TRIGGER update_chat_sessions_last_activity 
    BEFORE UPDATE ON chat_sessions 
    FOR EACH ROW 
    EXECUTE FUNCTION update_last_activity_column();

-- Create trigger to automatically update updated_at for user_personas
CREATE TRIGGER update_user_personas_updated_at 
    BEFORE UPDATE ON user_personas 
    FOR EACH ROW 
    EXECUTE FUNCTION update_updated_at_column();

-- Create trigger to automatically update updated_at for user_intents
CREATE TRIGGER update_user_intents_updated_at 
    BEFORE UPDATE ON user_intents 
    FOR EACH ROW 
    EXECUTE FUNCTION update_updated_at_column();

-- Create trigger to automatically update updated_at for properties
CREATE TRIGGER update_properties_updated_at 
    BEFORE UPDATE ON properties 
    FOR EACH ROW 
    EXECUTE FUNCTION update_updated_at_column();

-- Insert some sample properties for testing
INSERT INTO properties (title, description, location, city, address, size_sqm, price, price_type, listing_url, images, features, is_active, is_featured) VALUES
(
    '2-3 person office space in Edenvale',
    'Modern office space perfect for small teams',
    'Edenvale',
    'Johannesburg',
    'Greenstone Shopping Centre, 1 Emerald Boulevard, Modderfontein, 1609, South Africa',
    40,
    15000,
    'monthly',
    'https://example.com/office-edenvale',
    ARRAY['https://example.com/image1.jpg', 'https://example.com/image2.jpg'],
    ARRAY['3 phase power', 'Parking', 'Kitchen', 'Meeting room'],
    TRUE,
    TRUE
),
(
    'Warehouse space in Sandton',
    'Large warehouse space with loading dock',
    'Sandton',
    'Johannesburg',
    'Sandton City Shopping Centre, 83 Rivonia Rd, Sandhurst, Sandton, 2196, South Africa',
    200,
    25000,
    'monthly',
    'https://example.com/warehouse-sandton',
    ARRAY['https://example.com/warehouse1.jpg'],
    ARRAY['Loading dock', '3 phase power', 'Security', '24/7 access'],
    TRUE,
    FALSE
),
(
    'Small office in Cape Town CBD',
    'Cozy office space in the heart of Cape Town',
    'CBD',
    'Cape Town',
    'V&A Waterfront, Dock Rd, Cape Town, 8001, South Africa',
    25,
    12000,
    'monthly',
    'https://example.com/office-cape-town',
    ARRAY['https://example.com/cape-town1.jpg'],
    ARRAY['Air conditioning', 'High-speed internet', 'Reception'],
    TRUE,
    FALSE
)
ON CONFLICT DO NOTHING;