Skip to content

Commit b8cbbfa

Browse files
committed
fix(new beacon): 🐛 capture, store and return a Beacon
1 parent 357613b commit b8cbbfa

File tree

23 files changed

+280
-203
lines changed

23 files changed

+280
-203
lines changed

.cursor/rules/beacons.mdc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
description: deno & neo4
3+
globs:
4+
alwaysApply: false
5+
---
6+
Always refer to the documentation for the latest version of neo4j and deno

api/neo4j/find.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import neo4j, { Driver } from "neo4j";
2-
import { creds as c } from "utils/creds/neo4j.ts";
2+
import { creds as c } from "../../utils/auth/neo4jCred.ts";
33

44
export async function findUserById(
55
id: number,

api/neo4j/get.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import neo4j, { Driver } from "neo4j";
2-
import { creds as c } from "utils/creds/neo4j.ts";
2+
import { creds as c } from "../../utils/auth/neo4jCred.ts";
33

44
export async function getNouns() {
55
let driver: Driver | null = null;

api/neo4j/reset.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import neo4j, { Driver } from "neo4j";
2-
import { creds as c } from "../../utils/creds/neo4j.ts";
2+
import { creds as c } from "../../utils/auth/neo4jCred.ts";
33

44
export async function reset() {
55
let driver: Driver, result;

api/neo4j/seed.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import neo4j, { Driver } from "neo4j";
2-
import { creds } from "../../utils/creds/neo4j.ts";
2+
import { creds } from "../../utils/auth/neo4jCred.ts";
33

44
const data = JSON.parse(
55
await Deno.readTextFile("./data/seeds/facSeed.json"),

api/neo4j/writeBeacon.ts

Lines changed: 101 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,131 @@
11
import * as dotenv from "dotenv";
22
import neo4j, { Driver } from "neo4j";
3-
import type { Lantern, Beacon, Ash } from "types/beaconTypes.ts";
4-
import { creds as c } from "utils/creds/neo4j.ts";
3+
import type { Lantern, Ash, Ember, DBError } from "types/beaconTypes.ts";
4+
import type { Attempt } from "types/serverTypes.ts";
5+
import { creds as c } from "utils/auth/neo4jCred.ts";
56

67
dotenv.load({ export: true });
78

8-
export async function writeBeacons(entries:Lantern[]) {
9-
console.groupCollapsed(`====== FUNCTION writeBeacons(${entries.length} entries) ======`);
10-
let i = 0;
11-
for (const entry of entries) {
12-
console.log(`Passing Beacon ${i}: "${entry.input}"`);
13-
await writeBeacon(entry);
14-
i++;
15-
};
16-
console.groupEnd();
17-
}
18-
19-
export async function writeBeacon(entry:Lantern):Promise<Beacon | Ash> {
9+
export async function writeBeacon(entry:Lantern):Promise<Attempt> {
2010
console.groupCollapsed(`====== FUNCTION writeBeacon(${entry.input}) ======`);
21-
let driver: Driver;
22-
let newEntry: Beacon | Ash;
23-
11+
12+
let driver: Driver | undefined;
13+
let attempt: Attempt;
14+
let attemptError: DBError | undefined;
15+
2416
try {
25-
console.groupCollapsed(`--- Neo4j ---`);
2617
console.info("Initialising Driver...");
2718
driver = neo4j.driver(c.URI, neo4j.auth.basic(c.USER, c.PASSWORD));
28-
console.info("Connecting to Aura...");
2919
await driver.getServerInfo();
30-
31-
console.info("Building Query Params...");
32-
const verbProps = {
33-
dbId: entry.id ?? "no id",
34-
presetId: entry.presetId ?? "no preset id",
35-
input: entry.input,
36-
atoms: {
37-
client: {
38-
subject: entry.atoms.client.subject,
39-
verb: entry.atoms.client.verb,
40-
object: entry.atoms.client.object,
41-
adverbial: entry.atoms.client.adverbial
42-
},
43-
server: {
44-
subject: entry.atoms.server.subject,
45-
verb: entry.atoms.server.verb,
46-
object: entry.atoms.server.object,
47-
adverbial: entry.atoms.server.adverbial
48-
}
49-
},
50-
isPublic: entry.isPublic ?? false,
51-
isArchived: entry.isArchived ?? false,
52-
isSnoozed: entry.isSnoozed ?? false,
53-
category: entry.category ?? "",
54-
actions: entry.actions ?? []
55-
};
20+
21+
const userId = entry.authId ? entry.authId : "test-auth-id";
5622

5723
console.info("Executing Cypher Query...");
5824
const result = await driver.executeQuery(
59-
`MERGE (s:User {name:$sName})-[v:VERB {input: $vInput}]->(o:Concept {name:$oName})
60-
SET v = $vProps
25+
`MERGE (s:User {name:$sProps.name})-[v:VERB]->(o:Concept {name:$oProps.name})
26+
SET v.dbId = randomUUID(),
27+
v += $vProps
6128
RETURN s, v, o`,
6229
{
63-
sName: entry.atoms.server.subject.head,
64-
vInput: verbProps.input,
30+
sProps: { name: entry.shards.subject.head },
31+
oProps: { name: entry.shards.object.head },
6532
vProps: {
66-
id: verbProps.id,
67-
presetId: verbProps.presetId,
68-
input: verbProps.input,
69-
name: verbProps.atoms.server.verb.head,
70-
atomsClientSubject: verbProps.atoms.client.subject,
71-
atomsClientVerb: verbProps.atoms.client.verb,
72-
atomsClientObject: verbProps.atoms.client.object,
73-
atomsClientAdverbial: verbProps.atoms.client.adverbial,
74-
atomsServerSubjectHead: verbProps.atoms.server.subject.head,
75-
atomsServerSubjectArticle: verbProps.atoms.server.subject.article,
76-
atomsServerSubjectQuantity: verbProps.atoms.server.subject.quantity,
77-
atomsServerSubjectDescriptors: verbProps.atoms.server.subject.descriptors,
78-
atomsServerSubjectPhrase: verbProps.atoms.server.subject.phrase,
79-
atomsServerVerbHead: verbProps.atoms.server.verb.head,
80-
atomsServerVerbPhrase: verbProps.atoms.server.verb.phrase,
81-
atomsServerVerbDescriptors: verbProps.atoms.server.verb.descriptors,
82-
atomsServerObjectHead: verbProps.atoms.server.object.head,
83-
atomsServerObjectArticle: verbProps.atoms.server.object.article,
84-
atomsServerObjectQuantity: verbProps.atoms.server.object.quantity,
85-
atomsServerObjectDescriptors: verbProps.atoms.server.object.descriptors,
86-
atomsServerObjectPhrase: verbProps.atoms.server.object.phrase,
87-
isPublic: verbProps.isPublic,
88-
isArchived: verbProps.isArchived,
89-
isSnoozed: verbProps.isSnoozed,
90-
category: verbProps.category,
91-
actions: verbProps.actions
92-
},
93-
oName: entry.atoms.server.object.head
94-
}, { database: "neo4j" }
33+
authId: userId,
34+
presetId: entry.presetId ?? "",
35+
input: entry.input,
36+
name: entry.shards.verb.head,
37+
atoms_subject: entry.atoms.subject,
38+
atoms_verb: entry.atoms.verb,
39+
atoms_object: entry.atoms.object,
40+
atoms_adverbial: entry.atoms.adverbial,
41+
shards_subject_head: entry.shards.subject.head,
42+
shards_subject_phrase: entry.shards.subject.phrase,
43+
shards_subject_article: entry.shards.subject.article,
44+
shards_subject_quantity: entry.shards.subject.quantity,
45+
shards_subject_descriptors: entry.shards.subject.descriptors,
46+
shards_verb_head: entry.shards.verb.head,
47+
shards_verb_phrase: entry.shards.verb.phrase,
48+
shards_verb_descriptors: entry.shards.verb.descriptors,
49+
shards_object_head: entry.shards.object.head,
50+
shards_object_phrase: entry.shards.object.phrase,
51+
shards_object_article: entry.shards.object.article,
52+
shards_object_quantity: entry.shards.object.quantity,
53+
shards_object_descriptors: entry.shards.object.descriptors,
54+
shards_adverbial: entry.shards.adverbial,
55+
isPublic: entry.isPublic ?? false,
56+
isArchived: entry.isArchived ?? false,
57+
isSnoozed: entry.isSnoozed ?? false,
58+
category: entry.category ?? "",
59+
actions: [],
60+
errorLogs: []
61+
}
62+
},
63+
{ database: "neo4j" }
9564
);
9665

97-
console.info(`Assembling Return Object...`);
98-
newEntry = {
99-
// ...entry,
100-
// id: result.records[0].get("id")
101-
subject: result.records[0].get("s"),
102-
verb: result.records[0].get("v"),
103-
object: result.records[0].get("o")
66+
const record = result.records[0].get("v").properties;
67+
68+
console.groupCollapsed(`Ember`);
69+
const ember: Ember = {
70+
authId: record.authId,
71+
dbId: record.dbId,
72+
presetId: record.presetId,
73+
input: record.input,
74+
atoms: {
75+
subject: record.atoms_subject,
76+
verb: record.atoms_verb,
77+
object: record.atoms_object,
78+
adverbial: record.atoms_adverbial
79+
},
80+
category: record.category,
81+
isPublic: record.isPublic,
82+
isArchived: record.isArchived,
83+
isSnoozed: record.isSnoozed,
84+
actions: record.actions,
85+
errorLogs: record.errorLogs
10486
};
87+
console.info(`Ember assembled`);
88+
console.log(ember);
89+
console.groupEnd();
90+
91+
attempt = { record: ember };
10592
} catch (err) {
106-
console.warn(`Connection error`);
107-
// console.warn(err);
93+
console.groupCollapsed(`--- Error ---`);
94+
95+
console.groupCollapsed(`Details`);
96+
console.warn(err);
10897
const cause = err instanceof Error ? err.cause : "Cause Unknown";
98+
console.info(`Error Cause:`);
10999
console.warn(cause);
100+
console.groupEnd();
110101

111-
newEntry = {
112-
...entry,
113-
errorLogs: [{ isError: true, errorCause: cause }]
114-
};
115-
116-
return newEntry as Ash;
102+
console.groupCollapsed(`Ash`);
103+
attemptError = { isError: true, errorCause: cause };
104+
attempt = {
105+
record: { ...entry, errorLogs: [attemptError] },
106+
error: attemptError
107+
}
108+
console.log(attempt);
109+
console.groupEnd();
110+
111+
console.groupEnd();
117112
} finally {
118113
console.info("Closing Driver...");
119114
driver?.close();
120-
console.groupEnd();
121115
}
122116

123-
console.groupCollapsed(`--- Return ---`);
124-
console.log(newEntry.shards.subject);
125-
console.log(newEntry.shards.verb);
126-
console.log(newEntry.shards.object);
127117
console.groupEnd();
128-
129-
return newEntry;
118+
console.info(`==================================================`);
119+
return attempt;
120+
}
121+
122+
export async function writeBeacons(entries:Lantern[]) {
123+
console.groupCollapsed(`====== FUNCTION writeBeacons(${entries.length} entries) ======`);
124+
let i = 0;
125+
for (const entry of entries) {
126+
console.log(`Passing Beacon ${i}: "${entry.input}"`);
127+
await writeBeacon(entry);
128+
i++;
129+
};
130+
console.groupEnd();
130131
}
Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,8 @@ These are the request formats for the endpoints that either (a) are working or (
7878

7979
Some of these will need to be updated to include the session token.
8080

81-
- [ ] tdHi: Add the blocked tasks from Notion to this file
82-
- [x] tdMd: Change the assignation of verb from `[ v:${verb.toUpperCase()} ]` to `[v:VERB { name:${verb} }]`
83-
- [ ] tdHi: Update endpoints to allow receipt of auth token
81+
- [ ] tdWait: Update endpoints to allow receipt of auth token
82+
8483
- [ ] tdCheck: What's the type of driver??
8584

8685
### 2B. `"/edit/*"`
@@ -154,20 +153,22 @@ It's a `POST` endpoint because it's designed to take a JSON body.
154153

155154
#### 2X2. `GET "/get/v"`
156155

157-
- [ ] tdMd: Retrieve `verb.input` instead of `typeOf(verb)`
156+
- [ ] tdLo: Retrieve `verb.input` instead of `typeOf(verb)`
158157

159158
### 2D. `/write/*`
160159

161160
#### 2D1. `POST "/write/newBeacon"`
162161

163-
- [ ] tdHi: Correctly assign nested props to `beacon`
162+
- [ ] tdHi: Generate a unique `dbID` prop on new `Beacon`
163+
- [ ] tdHi: Correctly assign nested props to `Beacon`
164+
164165
- [ ] tdWait: Use `authID` for matching subject node
165-
- [ ] tdIdea: Call `breaker(match.atoms)` instead of `breaker(match)` so that they are identical
166-
- [ ] tdLo: Move term extraction from `breaker(match)` to a subfunction
167-
- [ ] tdHi: Create a unique `dbId` prop when creating a node
168-
- [ ] tdWait: Return `ember.dbId` to the frontend when creating new statements
169-
- [ ] tdWait: Create a unique `dbId` prop `ember.dbId` to the frontend when creating new statements
170-
- [ ] tdIdea: enforce the noun tag on `match.atoms.subject`
166+
- [ ] tdHi: Return `Ember.dbId` to the frontend when creating new statements
167+
168+
- [ ] tdLo: Move term extraction from `breaker(Match)` to a subfunction
169+
170+
- [ ] tdIdea: enforce the noun tag on `Match.atoms.subject`
171+
- [ ] tdIdea: Call `breaker(Match.atoms)` instead of `breaker(Match)` so that they are identical
171172

172173
This needs editing - I wrote it a few days ago, and at that point we were going to be passing userId from the client rather than generating it in the server.
173174

@@ -213,13 +214,15 @@ I'll also need to incorporate the authentication token into the request.
213214

214215
> WIP
215216
217+
- [ ] tdHi: Set the `authId` prop when creating a node
218+
216219
### 2E. `/auth/*`
217220

218221
#### 2E1. `POST "/auth/signin/magic-link"`
219222

220-
- [ ] tdWait: Create an endpoint that both signs in and creates a new user
221-
- [ ] tdWait: Create a new user node when a new user signs up
222-
- [ ] tdWait: Assign the managerEmail to the user node on creation
223+
- [ ] tdHi: Create an endpoint that both signs in and creates a new user
224+
- [ ] tdHi: Create a new user node when a new user signs up
225+
- [ ] tdHi: Assign the managerEmail to the user node on creation
223226

224227
```ts
225228
reqMagicLink(/* leads to "/" */);
@@ -238,6 +241,8 @@ I'll also need to incorporate the authentication token into the request.
238241

239242
#### 2E2. `GET "/auth/verify?token={token}"`
240243

244+
- [ ] tdHi: Create an auth route to verify the session token
245+
241246
Request is get with params
242247

243248
```ts
@@ -293,7 +298,7 @@ Request is `POST` with credentials included
293298

294299
#### 2F1. `POST "/send/ping"`
295300

296-
- [ ] tdHi: Pull the manager's email from the user node
301+
- [ ] tdWait: Pull the manager's email from the user node
297302

298303
```ts
299304
function sendPing(/* leads to "/" */): Promise<PingRes> {};

dev/SCRATCHPAD.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Cypher Scratchpad
2+
3+
```ts
4+
const verbProps = {
5+
dbId: entry.id ?? "no id",
6+
presetId: entry.presetId ?? "no preset id",
7+
input: entry.input,
8+
atoms: {
9+
subject: entry.atoms.subject,
10+
verb: entry.atoms.verb,
11+
object: entry.atoms.object,
12+
adverbial: entry.atoms.adverbial
13+
},
14+
shards: {
15+
subject: entry.atoms.server.subject,
16+
verb: entry.atoms.server.verb,
17+
object: entry.atoms.server.object,
18+
adverbial: entry.atoms.server.adverbial
19+
},
20+
isPublic: entry.isPublic ?? false,
21+
isArchived: entry.isArchived ?? false,
22+
isSnoozed: entry.isSnoozed ?? false,
23+
category: entry.category ?? "",
24+
actions: entry.actions ?? []
25+
}
26+
```
File renamed without changes.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import nlp from "npm:[email protected]";
2-
import { breaker } from "../language/breaker.ts";
2+
import { breaker } from "../utils/convert/breakInput.ts";
33

44
const input = Deno.args.join(" ");
55

0 commit comments

Comments
 (0)