Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #17 from ghost-in-the-machine-llc/db-migration
Db migration
- Loading branch information
Showing
37 changed files
with
1,686 additions
and
231 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
# General supabase access token (all projects) | ||
SUPABASE_ACCESS_TOKEN= | ||
# Supabase Project | ||
SUPABASE_DB_PASSWORD= | ||
SUPABASE_PROJECT_ID= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,5 @@ node_modules | |
*.env | ||
# Local Netlify folder | ||
.netlify | ||
# saved postman responses | ||
response |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"cSpell.words": [ | ||
"djwt" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"imports": { | ||
"@supabase": "https://esm.sh/@supabase/supabase-js@2/", | ||
"@supabase/types": "https://esm.sh/@supabase/supabase-js@2/dist/module/index.d.ts", | ||
"@supabase/gotrue-helpers": "https://esm.sh/v133/@supabase/gotrue-js@2.57.0/dist/module/lib/helpers.js", | ||
"http/status": "https://deno.land/std/http/status.ts", | ||
"@x/djwt": "https://deno.land/x/djwt@v3.0.0/mod.ts" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"cSpell.words": [ | ||
"nosniff", | ||
"openai", | ||
"PGRST", | ||
"Postgrest" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
import type { | ||
PostgrestMaybeSingleResponse, | ||
PostgrestSingleResponse, | ||
SupabaseClient, | ||
} from '@supabase/types'; | ||
import type { Database } from '../schema.gen.ts'; | ||
import type { | ||
Healer, | ||
Service, | ||
SessionStatus, | ||
Step, | ||
} from '../database.types.ts'; | ||
import type { Message } from './openai.ts'; | ||
|
||
import { createServiceClient, handleResponse } from './supabase.ts'; | ||
import { getUserPayload } from './jwt.ts'; | ||
|
||
interface SessionInfo { | ||
id: number; | ||
step_id: number; | ||
status: SessionStatus; | ||
} | ||
|
||
interface Session { | ||
id: number; | ||
step_id: number; | ||
healer: Healer; | ||
service: Service; | ||
} | ||
|
||
interface NewMoment { | ||
step_id: number; | ||
messages: Message[]; | ||
response: string; | ||
} | ||
|
||
export enum Status { | ||
Created = 'created', | ||
Active = 'active', | ||
Done = 'done', | ||
} | ||
|
||
export class HealingSessionManager { | ||
// #userClient: SupabaseClient<Database>; | ||
#serviceClient: SupabaseClient<Database>; | ||
#uid: string; | ||
// This is "healing session", not a server session | ||
#sessionId: number; | ||
|
||
constructor(userToken: string, sessionId: number) { | ||
const payload = getUserPayload(userToken); | ||
this.#uid = payload.sub; | ||
this.#sessionId = sessionId; | ||
|
||
// this.#userClient = createClient(userToken); | ||
this.#serviceClient = createServiceClient(); | ||
} | ||
|
||
async getOpenSessionInfo(): Promise<SessionInfo> { | ||
const res: PostgrestMaybeSingleResponse<SessionInfo> = await this | ||
.#serviceClient | ||
.from('session') | ||
.select(` | ||
id, | ||
step_id, | ||
status | ||
`) | ||
// eventually add service_id and healer_id | ||
.eq('id', this.#sessionId) | ||
.eq('uid', this.#uid) | ||
.maybeSingle(); | ||
|
||
return await handleResponse(res); | ||
} | ||
|
||
async getFullSessionInfo(): Promise<Session> { | ||
const res: PostgrestSingleResponse<Session> = await this | ||
.#serviceClient | ||
.from('session') | ||
.select(` | ||
id, | ||
healer(*), | ||
service(*), | ||
step_id | ||
`) | ||
// eventually add service_id and healer_id | ||
.eq('id', this.#sessionId) | ||
.eq('uid', this.#uid) | ||
.neq('status', Status.Done) | ||
.single(); | ||
|
||
return await handleResponse(res); | ||
} | ||
|
||
async getStepAfter(stepId: number | null): Promise<Step> { | ||
let query = this.#serviceClient | ||
.from('step') | ||
.select(); | ||
query = stepId | ||
? query.eq('prior_id', stepId) | ||
: query.is('prior_id', null); | ||
|
||
const res: PostgrestMaybeSingleResponse<Step> = await query | ||
.maybeSingle(); | ||
|
||
return handleResponse(res); | ||
} | ||
|
||
async #updateSession(update: object): Promise<void> { | ||
const { error } = await this.#serviceClient | ||
.from('session') | ||
.update(update) | ||
.eq('id', this.#sessionId); | ||
|
||
if (error) throw error; | ||
} | ||
|
||
updateSessionStep(stepId: number): Promise<void> { | ||
return this.#updateSession({ step_id: stepId, status: Status.Active }); | ||
} | ||
|
||
updateSessionStatus(status: SessionStatus): Promise<void> { | ||
return this.#updateSession({ status }); | ||
} | ||
|
||
async getPriorMessages(stepId: number | null): Promise<Message[]> { | ||
if (!stepId) return []; | ||
|
||
const res = await this.#serviceClient | ||
.from('moment') | ||
.select('*') | ||
.match({ | ||
session_id: this.#sessionId, | ||
step_id: stepId, | ||
uid: this.#uid, | ||
}) | ||
.single(); | ||
|
||
const data = handleResponse(res)!; | ||
return JSON.parse(<string> data.messages).messages; | ||
} | ||
|
||
async saveMoment(moment: NewMoment): Promise<void> { | ||
// PG doesn't deal with whole arrays in json columns, | ||
// so we make it an object... :shrug: | ||
const messages = { | ||
messages: [ | ||
...moment.messages, | ||
{ role: 'assistant', content: moment.response }, | ||
], | ||
}; | ||
|
||
const { error } = await this.#serviceClient | ||
.from('moment') | ||
.insert({ | ||
...moment, | ||
// parse the response string as JSON to decode | ||
// encoded characters like \", \', \n, etc. | ||
response: JSON.parse(JSON.stringify(moment.response)), | ||
messages: JSON.stringify(messages), | ||
uid: this.#uid, | ||
session_id: this.#sessionId, | ||
}); | ||
|
||
if (error) throw error; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { Status, STATUS_TEXT } from 'http/status'; | ||
|
||
export class HttpError extends Error { | ||
statusCode = Status.InternalServerError; | ||
statusText = STATUS_TEXT[Status.InternalServerError]; | ||
|
||
constructor(statusCode: Status, message: string, statusText?: string) { | ||
super(message); | ||
this.statusCode = statusCode; | ||
this.statusText = statusText || STATUS_TEXT[statusCode]; | ||
} | ||
} | ||
|
||
export class NoDataError extends Error {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { decodeJWTPayload } from '@supabase/gotrue-helpers'; | ||
|
||
// const encoder = new TextEncoder(); | ||
// const secret = Deno.env.get('JWT_SECRET'); | ||
// const keyBuffer = encoder.encode(secret); | ||
|
||
// const keyPromise = crypto.subtle.importKey( | ||
// 'raw', | ||
// keyBuffer, | ||
// { name: 'HMAC', hash: 'SHA-256' }, | ||
// true, | ||
// ['sign', 'verify'], | ||
// ); | ||
|
||
export function getUserPayload(token: string) { | ||
return decodeJWTPayload(token); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.