Skip to content

Commit 6d20056

Browse files
committed
feat(pings): ✨ send a list of public beacons when the route is called
1 parent a71cc4c commit 6d20056

File tree

11 files changed

+119
-152
lines changed

11 files changed

+119
-152
lines changed

api/neo4j/find.ts

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import neo4j, { Driver } from "neo4j";
22
import { creds as c } from "../../utils/auth/neo4jCred.ts";
33

4-
export async function findUserById(
5-
id: number,
6-
publicOnly: boolean = true
7-
):Promise<string[]> {
8-
console.group(`=== Running findUserById() ===`);
9-
console.log(`Received (id: ${id}, publicOnly: ${publicOnly})`);
4+
export async function findUserById( authId: string, publicOnly: boolean = true ):Promise<string[]> {
5+
console.group(`|=== findUserById() ===`);
6+
console.info(`| Parameters`);
7+
console.table([
8+
{is: "authId", value: authId},
9+
{is: "publicOnly", value: publicOnly}
10+
])
1011

1112
let driver: Driver | null = null, records, result;
1213
const statements:string[] = [];
@@ -17,22 +18,22 @@ export async function findUserById(
1718

1819
console.info(`Selecting Query Type`);
1920

20-
if (id && publicOnly) {
21-
console.info(`Query: Public Beacons for user #${id}`);
21+
if (authId && publicOnly) {
22+
console.info(`Query: Public Beacons for user #${authId}`);
2223
result = await driver.executeQuery(
2324
`MATCH statement =
24-
(user {id: $id})-[link {isPublic: true}]-()
25+
(user {authId: $authId})-[link {isPublic: true}]-()
2526
RETURN statement`,
26-
{ id },
27+
{ authId },
2728
{database: 'neo4j'}
2829
);
29-
} else if (id && !publicOnly) {
30-
console.info(`Query: All Beacons for user #${id}`);
30+
} else if (authId && !publicOnly) {
31+
console.info(`Query: All Beacons for user #${authId}`);
3132
result = await driver.executeQuery(
3233
`MATCH statement =
33-
(user {id: $id})-[link]-()
34+
(user {authId: $authId})-[link]-()
3435
RETURN statement`,
35-
{ id },
36+
{ authId },
3637
{database: 'neo4j'}
3738
);
3839
} else {
@@ -69,24 +70,24 @@ export async function findUserById(
6970
return statements;
7071
}
7172

72-
export async function findUserByName(
73-
name: string,
74-
publicOnly: boolean = true
75-
): Promise<string[]> {
73+
export async function findUserByName( name: string, publicOnly: boolean = true ): Promise<string[]> {
7674
console.group(`|=== findUserByName() ===`);
75+
console.info(`| Parameters`);
7776
console.table([
7877
{is: "name", value: name},
7978
{is: "publicOnly", value: publicOnly}
8079
])
8180

82-
let driver:(Driver|null) = null;
83-
let records, result;
81+
let driver: Driver | undefined;
8482
const statements:string[] = [];
8583

8684
try {
85+
console.info("| Initialising Driver...");
8786
driver = neo4j.driver(c.URI, neo4j.auth.basic(c.USER, c.PASSWORD));
8887
await driver.getServerInfo();
8988

89+
let result;
90+
9091
if (name && publicOnly) {
9192
result = await driver.executeQuery(
9293
`MATCH (s)-[v {isPublic: true}]-(o)
@@ -104,22 +105,21 @@ export async function findUserByName(
104105
{database: 'neo4j'}
105106
);
106107
}
107-
records = result?.records;
108+
109+
for (const record of result.records) { statements.push(record.get("v").properties.input) };
108110

109-
if (records) for (const record of records) {
110-
console.log(record);
111-
statements.push(record.get("v"));
112-
}
111+
console.info(`| Return`);
112+
console.table(statements);
113113
} catch (err) {
114-
console.error(`Neo4j Error: ${err}`);
114+
console.error(`| Neo4j Error: ${err}`);
115115
} finally {
116-
console.info(`Closing Driver`);
116+
console.info(`| Closing Driver`);
117117
await driver?.close();
118-
console.info(`Driver Closed`);
118+
console.info(`| Driver Closed`);
119119
}
120120

121121
console.groupEnd();
122-
console.info("========================");
122+
console.info("|========================");
123123

124124
return statements;
125125
}

api/neo4j/writeBeacon.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import { creds as c } from "utils/auth/neo4jCred.ts";
77
dotenv.load({ export: true });
88

99
export async function writeBeacon(entry:Lantern):Promise<Attempt> {
10-
console.groupCollapsed(`====== FUNCTION writeBeacon(${entry.input}) ======`);
10+
console.groupCollapsed(`|=== writeBeacon(${entry.input}) ===`);
11+
console.table([
12+
{is: "input", value: entry.input}
13+
])
1114

1215
let driver: Driver | undefined;
1316
let attempt: Attempt;

api/resend/sendPing.ts

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,20 @@ import { buildPing } from "content/builders/buildPing.ts";
44
const resendKey = Deno.env.get("RESEND_KEY");
55

66
export async function sendPing (
7-
authId: number,
7+
authId: string,
88
userName: string,
9-
readerName: string,
10-
readerEmail: string
9+
managerName: string,
10+
managerEmail: string
1111
): Promise<Response | Error> {
12-
console.group(`|=== Running sendPing() ===`);
12+
console.group(`|=== sendPing() ===`);
13+
console.info(`| Parameters`);
1314
console.table([
1415
{is: "authId", value: authId},
1516
{is: "userName", value: userName},
16-
{is: "readerName", value: readerName},
17-
{is: "readerEmail", value: readerEmail}
17+
{is: "managerName", value: managerName}
1818
])
1919

20-
console.group(`|=== Calling buildPing() ===`);
21-
console.log(`| Sending (${authId}, ${userName}, ${readerName})`);
22-
const content:PingInfo = await buildPing(authId, userName, readerName);
23-
console.groupEnd();
24-
console.info(`|===========================`);
20+
const content:PingInfo = await buildPing(authId, userName, managerName);
2521

2622
if (content.isValid) {
2723
console.info(`| Fetching from Resend API`);
@@ -33,7 +29,7 @@ export async function sendPing (
3329
},
3430
body: JSON.stringify({
3531
from: 'Beacons <[email protected]>',
36-
to: `${readerName} <${readerEmail}>`,
32+
to: `${managerName} <${managerEmail}>`,
3733
subject: `${userName} Lit a Beacon`,
3834
html: content.content,
3935
}),
@@ -42,7 +38,7 @@ export async function sendPing (
4238
if (res.ok) {
4339
const data = await res.json();
4440
console.info(`| Email sent successfully`);
45-
console.log(data);
41+
console.table(data);
4642

4743
console.groupEnd();
4844
console.info(`|===========================`);
@@ -53,7 +49,7 @@ export async function sendPing (
5349
});
5450
} else {
5551
const errorData = await res.text();
56-
console.warn("| Error:", errorData);
52+
console.warn(`| Error: ${errorData}`);
5753

5854
console.groupEnd();
5955
console.info(`|===========================`);
@@ -64,6 +60,6 @@ export async function sendPing (
6460
console.groupEnd();
6561
console.info(`|===========================`);
6662

67-
return new Error(`| Cannot send email: No entries to send`);
63+
return new Error(`Cannot send email: No entries to send`);
6864
}
6965
};

content/builders/buildPing.ts

Lines changed: 21 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,32 @@
11
import { findUserById, findUserByName } from "neo4jApi/find.ts";
22
import { generatePing } from "content/generators/generatePing.ts";
3+
import { PingInfo } from "types/pingTypes.ts";
34

4-
export async function buildPing(authId: number = 0, userName: string, managerName: string) {
5-
console.group(`|=== Running buildPing() ===`);
6-
console.log(`| Received (${authId}, ${userName}, ${managerName})`);
7-
8-
let entries: string[] = [];
9-
10-
if (authId != 0) {
11-
console.log(`| authId is ${authId}`);
12-
console.group(`|=== Calling findUserById() ===`);
13-
console.table([
14-
{is: "authId", value: authId},
15-
{is: "publicOnly", value: userName}
16-
])
17-
entries = await findUserById(authId, true);
18-
console.groupEnd();
19-
console.info(`|==========================`);
20-
} else {
21-
console.log(`| authId is ${authId}`);
22-
console.group(`|=== Calling findUserByName() ===`);
23-
console.table([
24-
{is: "userName", value: userName},
25-
{is: "publicOnly", value: true}
26-
])
27-
entries = await findUserByName(userName, true);
28-
console.groupEnd();
29-
console.info(`|==========================`);
30-
}
5+
export async function buildPing(authId: string, userName: string, managerName: string) {
6+
console.group(`|=== buildPing() ===`);
7+
console.info(`| Parameters`);
8+
console.table([
9+
{is: "authId", value: authId},
10+
{is: "userName", value: userName},
11+
{is: "managerName", value: managerName}
12+
])
13+
14+
const entries = authId != "0" ?
15+
await findUserById(authId, true) :
16+
await findUserByName(userName, true);
17+
18+
const ping: PingInfo = generatePing(entries, userName, managerName);
3119

32-
if (entries.length > 0) {
33-
console.groupCollapsed(`|=== Beacon Log ===`);
34-
for (let x = 0; x < entries.length; x++) {
35-
console.log(`| Beacon ${x + 1}${entries[x]}`);
36-
};
37-
console.groupEnd();
38-
console.info(`|==================`);
39-
}
20+
!ping.isValid ?
21+
console.warn(`| No beacons found for ${userName}`) :
22+
console.log(`| Ping for ${userName} generated successfully`);
4023

41-
console.group(`|=== Calling generatePing() ===`);
42-
const content = generatePing(entries, userName, managerName);
43-
44-
if (!content.isValid) {
45-
console.warn(`| Cannot send email: No beacons found for ${userName}`);
46-
} else {
47-
console.log(`| Email generated successfully`);
48-
}
24+
console.group(`|--- Ping to Send ---`);
25+
console.log(ping);
4926
console.groupEnd();
50-
console.info(`|==============================`);
5127

5228
console.groupEnd();
5329
console.info(`|===========================`);
5430

55-
return content;
31+
return ping
5632
}

content/generators/generatePing.ts

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,43 @@
1-
import { PingProps, PingInfo } from "types/pingTypes.ts";
1+
import { PingInfo } from "types/pingTypes.ts";
22

3-
export function generatePing(entries: string[], userName: string, managerName: string) {
4-
console.groupCollapsed(`|=== Running generatePing() ===`);
5-
6-
console.group(`| Parameters`);
7-
console.table([ /* Show Parameters */
3+
export function generatePing(entries: string[], userName: string, managerName: string): PingInfo {
4+
console.groupCollapsed(`|=== generatePing() ===`);
5+
console.info(`| Parameters`);
6+
console.table([
87
{ is: "entries", value: entries },
98
{ is: "userName", value: userName },
109
{ is: "managerName", value: managerName }
1110
]);
12-
console.groupEnd();
1311

14-
console.group(`| New Ping`);
1512
const ping = new PingInfo();
16-
console.table([ /* Show Ping */
13+
console.info(`| New Ping`);
14+
console.table([
1715
{is: "isValid", value: ping.isValid},
18-
{is: "content", value: ping.content}
16+
{is: "content length", value: ping.content?.length}
1917
])
20-
console.groupEnd();
2118

2219
const quantity = entries.length;
2320
const noun = quantity == 1 ? "beacon" : "beacons";
2421
const article = quantity >= 2 ? "some" : quantity == 1 ? "a " : "no";
2522

26-
console.group(`| Final Ping`);
2723
if (quantity >= 1) {
2824
ping.isValid = true;
29-
ping.content = (`<div><p>
30-
Hi ${managerName},
31-
<br/><br/>
32-
${userName} has shared ${article} ${noun} with you.
33-
<br/><br/>
25+
ping.content = (`<div>
26+
<p>Hi ${managerName},</p>
27+
<p>${userName} has shared ${article} ${noun} with you.</p>
3428
<ul>
3529
${entries.map(entry => `<li>${entry}</li>`).join('')}
3630
</ul>
37-
</p></div>`);
31+
</div>`);
3832
}
39-
console.table([ /* Show Ping */
33+
console.info(`| Return`);
34+
console.table([
4035
{is: "isValid", value: ping.isValid},
41-
{is: "content", value: ping.content}
36+
{is: "content length", value: ping.content?.length}
4237
])
43-
console.groupEnd();
4438

4539
console.groupEnd();
4640
console.info(`|==============================`);
41+
4742
return ping;
4843
}

dev/ENDPOINTS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ Some of these will need to be updated to include the session token.
121121

122122
This is the endpoint you should call to get the list of entries to show on the user's screen.
123123

124+
- [ ] tdHi: Refine the verb data included in the return object
125+
<!-- note: Implement logIn -->
124126
- [ ] tdWait: This should check for and pass the authentication ID
125127

126128
It's a `POST` endpoint because it's designed to take a JSON body.

main.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ async function customCors(ctx: Context, next: () => Promise<unknown>) {
1515
In production, FRONTEND_ORIGIN will be set (e.g., "https://lift-backend.deno.dev/").
1616
In development, it will default to "*" if not provided.
1717
*/
18-
console.info(``);
19-
console.info(`------------------------------------------------`);
20-
console.info(``);
21-
console.log(`Allowed Origin ${allowedOrigin}`);
22-
console.info(``);
18+
console.info(`|`);
19+
console.info(`|-----------------------------------------------`);
20+
console.info(`|`);
21+
console.log(`| Allowed Origin ${allowedOrigin}`);
22+
console.info(`|`);
2323

2424
ctx.response.headers.set(
2525
"Access-Control-Allow-Origin",
@@ -51,12 +51,14 @@ app.use(router.allowedMethods());
5151
app.listen({ port });
5252

5353
console.info(``);
54-
console.info(`======================================`);
55-
console.info(`======[ WELCOME TO BEACONS ]======`);
56-
console.info(`============= Port ${port} ==============`);
57-
console.info(``);
58-
54+
console.info(`|====================================|`);
55+
console.info(`|=====| WELCOME | TO | BEACONS |=====|`);
56+
console.info(`|==============| ${port} |==============|`);
57+
console.info(`|`);
58+
console.groupCollapsed(`|=== DB Schema ===`);
5959
await constrainUser();
6060
await constrainVerb();
61+
console.groupEnd();
62+
console.info(`|================`);
6163

6264
Deno.cron("Keep the DB awake", nudgeSched, nudgeDb);

0 commit comments

Comments
 (0)