-
Notifications
You must be signed in to change notification settings - Fork 0
Get all users route #69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
f852c0b
bd102d8
c4fd9eb
bd3d8b0
4603e63
490469e
2f7bde9
fa2927e
6ce5544
4e10066
b9acb6f
e3f714d
c8ebd7e
4cf1d95
f4761be
a462b45
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| DATABASE_URL=postgresql://branch_dev:password@localhost:5432/branch_db | ||
| DATABASE_URL=postgresql://branch_dev:password@localhost:5433/branch_db | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| DROP SCHEMA IF EXISTS branch CASCADE; | ||
| CREATE SCHEMA branch; | ||
| SET search_path TO branch; | ||
|
|
||
| CREATE TABLE users ( | ||
| user_id SERIAL PRIMARY KEY, | ||
| name VARCHAR(100) NOT NULL, | ||
| email VARCHAR(150) UNIQUE NOT NULL, | ||
| is_admin BOOLEAN DEFAULT FALSE, | ||
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | ||
| ); | ||
|
|
||
| CREATE TABLE projects ( | ||
| project_id SERIAL PRIMARY KEY, | ||
| name VARCHAR(100) NOT NULL, | ||
| total_budget NUMERIC(12,2), | ||
| start_date DATE, | ||
| end_date DATE, | ||
| currency VARCHAR(10) DEFAULT 'USD', | ||
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | ||
| ); | ||
|
|
||
| CREATE TABLE project_memberships ( | ||
| membership_id SERIAL PRIMARY KEY, | ||
| project_id INT NOT NULL REFERENCES projects(project_id) ON DELETE CASCADE, | ||
| user_id INT NOT NULL REFERENCES users(user_id) ON DELETE CASCADE, | ||
| role VARCHAR(30) NOT NULL CHECK (role IN ('PI', 'Accountant', 'Staff', 'Admin')), | ||
| start_date DATE, | ||
| hours NUMERIC(6,2), | ||
| UNIQUE (project_id, user_id) | ||
| ); | ||
|
|
||
| CREATE TABLE donors ( | ||
| donor_id SERIAL PRIMARY KEY, | ||
| organization VARCHAR(150) NOT NULL, | ||
| contact_name VARCHAR(100), | ||
| contact_email VARCHAR(150), | ||
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | ||
| ); | ||
|
|
||
| CREATE TABLE project_donations ( | ||
| donation_id SERIAL PRIMARY KEY, | ||
| donor_id INT NOT NULL REFERENCES donors(donor_id) ON DELETE CASCADE, | ||
| project_id INT NOT NULL REFERENCES projects(project_id) ON DELETE CASCADE, | ||
| amount NUMERIC(12,2) NOT NULL CHECK (amount >= 0), | ||
| donated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | ||
| UNIQUE (donor_id, project_id) | ||
| ); | ||
|
|
||
| CREATE TABLE expenditures ( | ||
| expenditure_id SERIAL PRIMARY KEY, | ||
| project_id INT NOT NULL REFERENCES projects(project_id) ON DELETE CASCADE, | ||
| entered_by INT REFERENCES users(user_id) ON DELETE SET NULL, | ||
| amount NUMERIC(12,2) NOT NULL CHECK (amount >= 0), | ||
| category VARCHAR(50), | ||
| description TEXT, | ||
| spent_on DATE NOT NULL DEFAULT CURRENT_DATE, | ||
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | ||
| ); | ||
|
|
||
| INSERT INTO users (name, email, is_admin) VALUES | ||
| ('Ashley Duggan', 'ashley@branch.org', TRUE), | ||
| ('Renee Reddy', 'renee@branch.org', TRUE), | ||
| ('Nour Shoreibah', 'nour@branch.org', TRUE); | ||
|
|
||
| INSERT INTO projects (name, total_budget, start_date, end_date, currency) VALUES | ||
| ('Clinician Communication Study', 500000, '2025-01-01', '2026-01-01', 'USD'), | ||
| ('Health Education Initiative', 300000, '2025-03-01', '2026-03-01', 'USD'), | ||
| ('Policy Advocacy Program', 200000, '2025-06-01', '2026-06-01', 'USD'); | ||
|
|
||
| INSERT INTO donors (organization, contact_name, contact_email) VALUES | ||
| ('NIH', 'Dr. Sarah Lee', 'sarah@nih.gov'), | ||
| ('Harvard Medical', 'John Smith', 'john@harvard.edu'), | ||
| ('Wellcome Trust', 'Anna Johnson', 'anna@wellcome.org'); | ||
|
|
||
| INSERT INTO project_donations (donor_id, project_id, amount, donated_at) VALUES | ||
| (1, 1, 150000, '2025-01-10'), | ||
| (2, 2, 120000, '2025-03-15'), | ||
| (3, 3, 90000, '2025-06-20'); | ||
|
|
||
| INSERT INTO project_memberships (project_id, user_id, role, start_date, hours) VALUES | ||
| (1, 1, 'PI', '2025-01-01', 100.00), | ||
| (1, 2, 'Accountant', '2025-02-01', 80.00), | ||
| (2, 3, 'Staff', '2025-03-15', 60.00); | ||
|
|
||
| INSERT INTO expenditures (project_id, entered_by, amount, category, description, spent_on) VALUES | ||
| (1, 1, 5000, 'Travel', 'Conference attendance', '2025-02-10'), | ||
| (2, 2, 3000, 'Equipment', 'Purchase of recording devices', '2025-04-05'), | ||
| (3, 3, 2500, 'Supplies', 'Educational materials', '2025-07-12'); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda'; | ||
| import db from './db'; | ||
| import db from './db' | ||
|
|
||
|
|
||
| export const handler = async (event: any): Promise<APIGatewayProxyResult> => { | ||
| try { | ||
|
|
@@ -10,6 +11,8 @@ export const handler = async (event: any): Promise<APIGatewayProxyResult> => { | |
| const normalizedPath = rawPath.replace(/\/$/, ''); | ||
| const method = (event.requestContext?.http?.method || event.httpMethod || 'GET').toUpperCase(); | ||
|
|
||
| console.log('DEBUG - rawPath:', rawPath, 'normalizedPath:', normalizedPath, 'method:', method); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe remove if not needed anymore |
||
|
|
||
| // Health check | ||
| if ((normalizedPath.endsWith('/health') || normalizedPath === '/health') && method === 'GET') { | ||
| return json(200, { ok: true, timestamp: new Date().toISOString() }); | ||
|
|
@@ -18,7 +21,53 @@ export const handler = async (event: any): Promise<APIGatewayProxyResult> => { | |
| // >>> ROUTES-START (do not remove this marker) | ||
| // CLI-generated routes will be inserted here | ||
|
|
||
| // GET /{userId} (dev server strips /users prefix) | ||
|
|
||
| // GET /users | ||
| if ((normalizedPath === '/users' || normalizedPath === '' || normalizedPath === '/') && method === 'GET') { | ||
| // TODO: Add your business logic here | ||
| const queryParams = event.queryStringParameters || {}; | ||
| const page = queryParams.page ? parseInt(queryParams.page, 10) : null; | ||
| const limit = queryParams.limit ? parseInt(queryParams.limit, 10) : null; | ||
|
|
||
| if (page && limit) { | ||
| const offset = (page - 1) * limit; | ||
|
|
||
| const totalCount = await db | ||
| .selectFrom('branch.users') | ||
| .select(db.fn.count('user_id').as('count')) | ||
| .executeTakeFirst(); | ||
|
|
||
| const totalUsers = Number(totalCount?.count || 0); | ||
| const totalPages = Math.ceil(totalUsers / limit); | ||
|
|
||
| const users = await db | ||
| .selectFrom('branch.users') | ||
| .selectAll() | ||
mehanana marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| .orderBy('user_id', 'asc') | ||
| .limit(limit) | ||
| .offset(offset) | ||
| .execute(); | ||
| return json(200, { | ||
| users, | ||
| pagination: { | ||
| page, | ||
| limit, | ||
| totalUsers, | ||
| totalPages | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| const users = await db | ||
| .selectFrom('branch.users') | ||
| .selectAll() | ||
| .execute(); | ||
|
|
||
| console.log(users); | ||
| return json(200, { users }); | ||
| } | ||
|
|
||
| // GET /{userId} | ||
| if (normalizedPath.startsWith('/') && normalizedPath.split('/').length === 2 && method === 'GET') { | ||
nourshoreibah marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| const userId = normalizedPath.split('/')[1]; | ||
| if (!userId) return json(400, { message: 'userId is required' }); | ||
|
|
@@ -65,6 +114,7 @@ export const handler = async (event: any): Promise<APIGatewayProxyResult> => { | |
|
|
||
| return json(200, { ok: true, route: 'PATCH /users/{userId}', pathParams: { userId }, body: { email: updatedUser!.email, name: updatedUser!.name, isAdmin: updatedUser!.is_admin } }); | ||
| } | ||
|
|
||
| // <<< ROUTES-END | ||
|
|
||
| return json(404, { message: 'Not Found', path: normalizedPath, method }); | ||
|
|
@@ -85,4 +135,4 @@ function json(statusCode: number, body: unknown): APIGatewayProxyResult { | |
| }, | ||
| body: JSON.stringify(body) | ||
| }; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| module.exports = { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wait why was i able to run jest tests without this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i got an error when i tried to test and it worked when i deleted it |
||
| preset: 'ts-jest', | ||
| testEnvironment: 'node', | ||
| testMatch: ['**/*.test.ts'], | ||
| }; | ||
Uh oh!
There was an error while loading. Please reload this page.