From 5b54991ee2625fad96a86ffe3d2b469b4b8b6430 Mon Sep 17 00:00:00 2001 From: sounmind Date: Tue, 24 Dec 2024 10:52:12 -0500 Subject: [PATCH 1/4] feat: add db setup script --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 412cc68..5da19c8 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "format": "dprint fmt --staged", "typecheck": "tsc --noEmit", "lint:js": "eslint --fix", - "lint": "npm run typecheck && npm run lint:js" + "lint": "npm run typecheck && npm run lint:js", + "db:setup": "src/db/wrangler-development-script.sh" }, "dependencies": { "hono": "^4.6.12" From 4d1b62b7d4662a50d965a7fac2d9f665fdf39cbd Mon Sep 17 00:00:00 2001 From: sounmind Date: Tue, 24 Dec 2024 10:51:47 -0500 Subject: [PATCH 2/4] fix: getProfileById, getAllProfiles - Changed the table name(profiles -> profile) Co-authored-by: Manvinderjit Rupal --- src/controllers/sqlControllers/getProfiles.ts | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/controllers/sqlControllers/getProfiles.ts b/src/controllers/sqlControllers/getProfiles.ts index baacd45..0191b43 100644 --- a/src/controllers/sqlControllers/getProfiles.ts +++ b/src/controllers/sqlControllers/getProfiles.ts @@ -1,29 +1,26 @@ import type { Context } from 'hono'; import { StatusCodes } from '../../constants/status-codes.ts'; -import type { Profile } from '../../db/profile'; export const getProfileById = async (context: Context) => { - const userId = context.req.param("id"); + const userId = context.req.param('id'); try { - const { results } = await context.env.database.prepare( - "SELECT * FROM profiles WHERE id = ?", - ) - .bind(userId) - .run(); - return context.json(results); + const { results } = await context.env.database + .prepare('SELECT * FROM profile WHERE id = ?') + .bind(userId) + .run(); + return context.json(results); } catch (e) { - return context.json({ err: e.message }, StatusCodes.NOT_FOUND); + return context.json({ err: e.message }, StatusCodes.NOT_FOUND); } - }; +}; - export const getAllProfiles = async (context: Context) => { +export const getAllProfiles = async (context: Context) => { try { - let { results } = await context.env.database.prepare( - "SELECT * FROM profiles", - ) - .all(); - return context.json(results); + const { results } = await context.env.database + .prepare('SELECT * FROM profile') + .all(); + return context.json(results); } catch (e) { - return context.json({ err: e.message }, StatusCodes.NOT_FOUND); + return context.json({ err: e.message }, StatusCodes.NOT_FOUND); } - }; \ No newline at end of file +}; From cc61955c8789704e1f51462b5dfdd96d9e5ce639 Mon Sep 17 00:00:00 2001 From: sounmind Date: Tue, 24 Dec 2024 11:30:42 -0500 Subject: [PATCH 3/4] feat: delete profile - Added delete profile route and controller - Updated profile schema added "ON DELETE CASCADE" on FOREIGN KEY (profileId) Co-authored-by: Manvinderjit Rupal --- .../sqlControllers/deleteProfile.ts | 18 ++++++++++++++++++ src/db/wrangler-development-script.sh | 4 ++-- src/routes/profiles/profilesSql.ts | 13 ++++++------- 3 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 src/controllers/sqlControllers/deleteProfile.ts diff --git a/src/controllers/sqlControllers/deleteProfile.ts b/src/controllers/sqlControllers/deleteProfile.ts new file mode 100644 index 0000000..ac69eff --- /dev/null +++ b/src/controllers/sqlControllers/deleteProfile.ts @@ -0,0 +1,18 @@ +import type { Context } from 'hono'; +import { StatusCodes } from '../../constants/status-codes.ts'; + +export const deleteProfileById = async ( + context: Context +) => { + const userId = context.req.param('id'); + + try { + const { results } = await context.env.database + .prepare('DELETE FROM profile WHERE id = ?') + .bind(userId) + .run(); + return context.json(results); + } catch (error) { + return context.json({ err: error.message }, StatusCodes.NOT_FOUND); + } +}; diff --git a/src/db/wrangler-development-script.sh b/src/db/wrangler-development-script.sh index af34da4..d4f6e72 100755 --- a/src/db/wrangler-development-script.sh +++ b/src/db/wrangler-development-script.sh @@ -6,7 +6,7 @@ wrangler d1 execute vms-local-db --local --command "CREATE TABLE IF NOT EXISTS p wrangler d1 execute vms-local-db --local --command "CREATE TABLE IF NOT EXISTS team (id TEXT PRIMARY KEY NOT NULL UNIQUE COLLATE BINARY, schemaVersion INTEGER NOT NULL, name TEXT NOT NULL, description TEXT, happenedAt TEXT NOT NULL, insertedAt TEXT NOT NULL);" -wrangler d1 execute vms-local-db --local --command "CREATE TABLE IF NOT EXISTS role (id TEXT PRIMARY KEY NOT NULL UNIQUE COLLATE BINARY, schemaVersion INTEGER NOT NULL, role TEXT NOT NULL, description TEXT, teamId TEXT NOT NULL UNIQUE COLLATE BINARY, profileId TEXT NOT NULL UNIQUE COLLATE BINARY, happenedAt TEXT NOT NULL, insertedAt TEXT NOT NULL, FOREIGN KEY (teamId) REFERENCES team(id), FOREIGN KEY (profileId) REFERENCES profile(id));" +wrangler d1 execute vms-local-db --local --command "CREATE TABLE IF NOT EXISTS role (id TEXT PRIMARY KEY NOT NULL UNIQUE COLLATE BINARY, schemaVersion INTEGER NOT NULL, role TEXT NOT NULL, description TEXT, teamId TEXT NOT NULL UNIQUE COLLATE BINARY, profileId TEXT NOT NULL UNIQUE COLLATE BINARY, happenedAt TEXT NOT NULL, insertedAt TEXT NOT NULL, FOREIGN KEY (teamId) REFERENCES team(id), FOREIGN KEY (profileId) REFERENCES profile(id) ON DELETE CASCADE);" wrangler d1 execute vms-local-db --local --command "CREATE TABLE IF NOT EXISTS event_log (id TEXT PRIMARY KEY NOT NULL UNIQUE COLLATE BINARY, schemaVersion INTEGER NOT NULL, subject TEXT NOT NULL UNIQUE COLLATE BINARY, subjectSource TEXT NOT NULL DEFAULT 'profile' CHECK("subjectSource" IN ('profile', 'team', 'role', 'special')), verb TEXT NOT NULL, object TEXT NOT NULL UNIQUE COLLATE BINARY,objectSource TEXT NOT NULL DEFAULT 'special' CHECK("objectSource" IN ('profile', 'team', 'role', 'special')), happenedAt TEXT NOT NULL, insertedAt TEXT NOT NULL);" @@ -24,4 +24,4 @@ wrangler d1 execute vms-local-db --local --command "INSERT INTO role (id, schema # Insert dummy data into event_log table wrangler d1 execute vms-local-db --local --command "INSERT INTO event_log (id, schemaVersion, subject, subjectSource, verb, object, objectSource, happenedAt, insertedAt) VALUES ('1', 1, 'John Doe', 'profile', 'created', 'profile', 'profile', '2024-12-17T00:00:00Z', '2024-12-17T00:00:00Z');" -wrangler d1 execute vms-local-db --local --command "INSERT INTO event_log (id, schemaVersion, subject, subjectSource, verb, object, objectSource, happenedAt, insertedAt) VALUES ('2', 1, 'Team Alpha', 'team', 'created', 'team', 'team', '2024-12-17T00:00:00Z', '2024-12-17T00:00:00Z');" \ No newline at end of file +wrangler d1 execute vms-local-db --local --command "INSERT INTO event_log (id, schemaVersion, subject, subjectSource, verb, object, objectSource, happenedAt, insertedAt) VALUES ('2', 1, 'Team Alpha', 'team', 'created', 'team', 'team', '2024-12-17T00:00:00Z', '2024-12-17T00:00:00Z');" diff --git a/src/routes/profiles/profilesSql.ts b/src/routes/profiles/profilesSql.ts index 40d9c7e..e186df3 100644 --- a/src/routes/profiles/profilesSql.ts +++ b/src/routes/profiles/profilesSql.ts @@ -1,7 +1,9 @@ - import { Hono } from 'hono'; -import { getAllProfiles, getProfileById } from '../../controllers/sqlControllers/getProfiles'; - +import { deleteProfileById } from 'src/controllers/sqlControllers/deleteProfile'; +import { + getAllProfiles, + getProfileById +} from '../../controllers/sqlControllers/getProfiles'; const profilesSqlRoutes = new Hono(); @@ -9,9 +11,6 @@ const profilesSqlRoutes = new Hono(); profilesSqlRoutes.get('/', getAllProfiles); // Route to get a profile by ID -profilesSqlRoutes.get('/:id', getProfileById); +profilesSqlRoutes.get('/:id', getProfileById).delete('/:id', deleteProfileById); export default profilesSqlRoutes; - - - From 686df16e9bcf1f4a3d5f9c93e77ae9dc0022239c Mon Sep 17 00:00:00 2001 From: Lyla Date: Thu, 9 Jan 2025 22:40:59 -0500 Subject: [PATCH 4/4] feat: update API to fetch data from actual DB instead of mock data Co-authored-by: Evan Suhyeong Lee --- .../{sqlControllers => }/deleteProfile.ts | 2 +- src/controllers/getProfiles.ts | 30 ++++++++++++------- src/controllers/sqlControllers/getProfiles.ts | 26 ---------------- src/index.ts | 9 ++---- src/routes/profiles/profiles.ts | 10 ++++--- src/routes/profiles/profilesSql.ts | 16 ---------- 6 files changed, 29 insertions(+), 64 deletions(-) rename src/controllers/{sqlControllers => }/deleteProfile.ts (87%) delete mode 100644 src/controllers/sqlControllers/getProfiles.ts delete mode 100644 src/routes/profiles/profilesSql.ts diff --git a/src/controllers/sqlControllers/deleteProfile.ts b/src/controllers/deleteProfile.ts similarity index 87% rename from src/controllers/sqlControllers/deleteProfile.ts rename to src/controllers/deleteProfile.ts index ac69eff..a4c3dc5 100644 --- a/src/controllers/sqlControllers/deleteProfile.ts +++ b/src/controllers/deleteProfile.ts @@ -1,5 +1,5 @@ import type { Context } from 'hono'; -import { StatusCodes } from '../../constants/status-codes.ts'; +import { StatusCodes } from '../constants/status-codes.ts'; export const deleteProfileById = async ( context: Context diff --git a/src/controllers/getProfiles.ts b/src/controllers/getProfiles.ts index 90fc4c6..91561cb 100644 --- a/src/controllers/getProfiles.ts +++ b/src/controllers/getProfiles.ts @@ -1,16 +1,26 @@ import type { Context } from 'hono'; -import profiles from '../data/profiles.json'; import { StatusCodes } from '../constants/status-codes.ts'; -export const getAllProfiles = (context: Context) => context.json(profiles, StatusCodes.OKAY); - -export const getProfileById = (context: Context) => { - const id = context.req.param('id'); - const profile = profiles.find((currentProfile) => currentProfile.id === id); - - if (!profile) { - return context.json({ error: 'Profile not found' }, StatusCodes.NOT_FOUND); +export const getProfileById = async (context: Context) => { + const userId = context.req.param('id'); + try { + const { results } = await context.env.database + .prepare('SELECT * FROM profile WHERE id = ?') + .bind(userId) + .run(); + return context.json(results); + } catch (e) { + return context.json({ err: e.message }, StatusCodes.NOT_FOUND); } +}; - return context.json(profile, StatusCodes.OKAY); +export const getAllProfiles = async (context: Context) => { + try { + const { results } = await context.env.database + .prepare('SELECT * FROM profile') + .all(); + return context.json(results); + } catch (e) { + return context.json({ err: e.message }, StatusCodes.NOT_FOUND); + } }; diff --git a/src/controllers/sqlControllers/getProfiles.ts b/src/controllers/sqlControllers/getProfiles.ts deleted file mode 100644 index 0191b43..0000000 --- a/src/controllers/sqlControllers/getProfiles.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { Context } from 'hono'; -import { StatusCodes } from '../../constants/status-codes.ts'; - -export const getProfileById = async (context: Context) => { - const userId = context.req.param('id'); - try { - const { results } = await context.env.database - .prepare('SELECT * FROM profile WHERE id = ?') - .bind(userId) - .run(); - return context.json(results); - } catch (e) { - return context.json({ err: e.message }, StatusCodes.NOT_FOUND); - } -}; - -export const getAllProfiles = async (context: Context) => { - try { - const { results } = await context.env.database - .prepare('SELECT * FROM profile') - .all(); - return context.json(results); - } catch (e) { - return context.json({ err: e.message }, StatusCodes.NOT_FOUND); - } -}; diff --git a/src/index.ts b/src/index.ts index 220ef41..7fcd5c5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,11 +2,8 @@ import { Hono } from 'hono'; import { cors } from 'hono/cors'; import profilesRoute from './routes/profiles/profiles'; import teamsRoutes from './routes/teams/teams'; -import profilesSqlRoute from './routes/profiles/profilesSql'; import teamsSqlRoute from './routes/teams/teamsSql'; - - const app = new Hono(); app.get('/', (context) => context.text('Welome to volunteer management system!')); @@ -23,12 +20,10 @@ app.use( }) ); -// Existing routes app.route('/profiles', profilesRoute); -app.route('/teams', teamsRoutes); -app.route('/sql/profiles', profilesSqlRoute); +// TODO: should be changed to interact with real DB app.route('/sql/teams', teamsSqlRoute); - +app.route('/teams', teamsRoutes); export default app; diff --git a/src/routes/profiles/profiles.ts b/src/routes/profiles/profiles.ts index ebcfbb8..65ff846 100644 --- a/src/routes/profiles/profiles.ts +++ b/src/routes/profiles/profiles.ts @@ -1,5 +1,9 @@ import { Hono } from 'hono'; -import { getAllProfiles, getProfileById } from '../../controllers/getProfiles'; +import { deleteProfileById } from '../../controllers/deleteProfile'; +import { + getAllProfiles, + getProfileById +} from '../../controllers/getProfiles'; const profilesRoutes = new Hono(); @@ -7,8 +11,6 @@ const profilesRoutes = new Hono(); profilesRoutes.get('/', getAllProfiles); // Route to get a profile by ID -profilesRoutes.get('/:id', getProfileById); - - +profilesRoutes.get('/:id', getProfileById).delete('/:id', deleteProfileById); export default profilesRoutes; diff --git a/src/routes/profiles/profilesSql.ts b/src/routes/profiles/profilesSql.ts deleted file mode 100644 index e186df3..0000000 --- a/src/routes/profiles/profilesSql.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Hono } from 'hono'; -import { deleteProfileById } from 'src/controllers/sqlControllers/deleteProfile'; -import { - getAllProfiles, - getProfileById -} from '../../controllers/sqlControllers/getProfiles'; - -const profilesSqlRoutes = new Hono(); - -// Route to get all profiles -profilesSqlRoutes.get('/', getAllProfiles); - -// Route to get a profile by ID -profilesSqlRoutes.get('/:id', getProfileById).delete('/:id', deleteProfileById); - -export default profilesSqlRoutes;