Most everything I think you'll need to know/resources you'll need to work on this project.
Deployment to Heroku is done through Git.
- You can only access the Heroku app/use Heroku commands for the app via the CLI if you are in that app's repository/the location where you added the Heroku remote. So typing any app-associated Heroku commands will not work unless you're in that directory.
- Clone the passkeys-backend project to your development environment.
- Install the Heroku CLI.
- Log into the lab Heroku account in the heroku command line interface using
heroku login
(details in the link in step 2). - Navigate in the terminal to the folder where you cloned
passkeys-backend
so that you're inside thepasskeys-backend
directory. - Enter
heroku git:remote -a passkeys-backend
in the command line to add the Heroku remote to your local repository (see "For an Existing App" here for more information/help).
- Once you've committed changes to your local repository, type
git push heroku main
in the command line to deploy to the Heroku server. - Note to also push your commits to the
passkeys-backend
lab repository as well so that your teammates can have your updated code to work on.
- Use
heroku config
to see the set environment variables for the app. We have the database URL and the session secret saved as environment variables. If you need to set new ones, you'll need to do your own research on how to do so. Check the Heroku documentation, I think this is the page you want.
- To access the app's database directly, use
heroku pg:psql
. This will connect you to the database associated with the app (assuming you're in) - Some useful commands:
\dt
- display all tables in the databaseTABLE table_name;
- show the contents of a table with nametable_name
- Use other SQL commands to view/modify the database as needed (you're on your own). Don't forget semicolons where needed!
- You may need to type
q
to exit some commands. ctrl + Z
to exit the database connection.
- To view the logs of your running program, including log statements, error statements, etc., use
heroku logs
heroku logs --tail
is particularly useful to stay connected to the log feed during debugging
Store signed up users. Each user will have a profile row in TABLE profiles
which contains their Venmo profile information, but users
strictly contains information regarding authentication.
id
- user identifier - referenced by other tables as user_id, actor_id, target_idusername
- the username of the userhashed_password
- unusedsalt
- unusedname
- the user's display name, e.g. my full name, David Gaaghandle
- randomly generated uuid, created in/signup/public-key/challenge
- I'm not entirely sure what this does, to be honest
id
- the id of the public key rowuser_id
- the user's identifier (id
inTABLE user
)external_id
- I think this is thehandle
inTABLE users
public_key
- the public key of a user
Each user will have a profile row in TABLE profiles
which contains their Venmo profile information.
user_id
- the user's identifier (id
inTABLE user
)first_name
- the user's first name- NULL-able if never given
last_name
- NULL-able if never given
balance
- the user's account balance in fictional currency (never use dollars/$ for legal reasons)- Two decimal places
All transactions which have occurred on the platform/app, ever. Not deleted when a user deletes their profile (TODO?).
id
- the transaction's identifieractor_id
- the id of the user who initiated the transactiontarget_id
- the id of the target user of a transactionamount
- the amount in fictional currency of the transactionaction
- the action type of the transaction (see Definitions/Possible Values)status
- the status of the transaction (see Definitions/Possible Values)note
- the user-provided text of the transaction purpose/description, e.g. "Utilities"date_created
- the date the transaction was initiated (see Definitions/Possible Values for date format)date_completed
- the date the transaction was completed (see Definitions/Possible Values for date format)audience
- the audience that has permission to see this transaction (see Definitions/Possible Values)
A table containing friend/relationship/friend request data between users. user1_id
should/must ALWAYS be the lower of the pair of ids. This way, only one row is needed per relationship, and the relationship can always be found by querying the lower user's id.
user1_id
- the id of one of the users (always lower than correspondinguser2_id
)user2_id
- the id of the other user (always higher than correspondinguser1_id
)relationship
- the relationship between the users (see Definitions/Possible Values)
Definitions and valid values for the DATABASE VALUES. Note that request/response variables of the same name may have different valid/expected values; the values below apply only to entries in the database.
action
- The type of transaction- Valid/possible values:
pay
- the actor is paying the targetrequest
- the actor is requesting payment from the target
- Valid/possible values:
status
- The status of a transaction- Valid/possible values:
settled
- the transaction has been completed- Automatic for
pay
actions (if the user has sufficient funds) - Set for
request
when the request is either approved or denied
- Automatic for
pending
- the transaction is pending- When a
request
is made but not completed by the target
- When a
cancelled
- therequest
has been cancelled by the targetdenied
- therequest
has been denied by the target
- Valid/possible values:
- Date/Time format - Unix time (seconds since the Unix epoch, 00:00:00 UTC on 1 January 1970)
audience
- the audience that has permission to see the transaction- Valid/possible values:
private
- only the actor and the targetfriends
- friends of the actor and friends of the targetpublic
- any user
- Valid/possible values:
relationship
- the relationship/request status between two usersnone
friend
- the users are friendsuser1Requested
- user1 has requested to friend user2user2Requested
- user2 has requested to friend user1- TODO: Implement blocking?
- user_id PRIMARY KEY INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
- username TEXT UNIQUE NOT NULL,
- first_name TEXT,
- last_name TEXT
- id SERIAL PRIMARY KEY,
- payer_id INTEGER NOT NULL,
- payee_id INTEGER NOT NULL,
- amount REAL NOT NULL,
- action TEXT NOT NULL,
- status TEXT NOT NULL,
- note TEXT NOT NULL,
- date_created INTEGER NOT NULL,
- date_completed INTEGER,
- audience TEXT NOT NULL
- id
- username
- name (display name)
GET /me
Params:
- Session cookie Response Body:
{
"profile": {
"username": String,
"firstName": String,
"lastName": String,
"displayName": String,
"relationship": String,
"friendsCount": Int,
"id": Int,
"balance": Double
}
}
PUT /me
Parameters:
- firstName
- lastName No response body
GET /profiles/:userID
Params:
- none Response body:
{
"profile": {
"username": String,
"firstName": String,
"lastName": String,
"displayName": String,
"relationship": String, // me, none, friend, youRequested, theyRequested
"friendsCount": Int,
"id": Int
}
}
POST /profiles/:userID
Params:
- Session cookie
- Relationship (none, friend) Response body: None?
GET /profiles/:userID/friends
Params:
- none Response body:
{
"friends": [
{
"username": String,
"firstName": String,
"lastName": String,
"displayName": String,
"id": Int
},
{...},
...
]
}
DEFINITIONS
- relationship: me, none, friend, user1Requested, user2Requested, unknown (endpoint called without logging in) (TODO: blocked)
- Note: user1Requested and user2Requested are server-side only (in database). Response will contain either youRequested or theyRequested
GET /profiles
Performs search by username.
Params:
- query
- limit (optional) Response body:
{
"profiles": [
{...},
...
]
}
POST /transactions
Params:
- Session cookie
- Target id
- Amount
- Action
- Note
- Audience Response body:
{
"id": Int,
"balance": Double,
"amount": Double,
"action": String,
"status": String,
"note": String,
"dateCreated": Date,
"dateCompleted": Date,
"audience": String,
"actor": {
"id": Int,
"username": String,
"firstName": String,
"lastName": String,
"displayName": String,
},
"target": {
"id": Int,
"username": String,
"firstName": String,
"lastName": String,
"displayName": String,
}
}
GET /transactions
Params:
- Session cookie
- Feed (friends, user, betweenUs) (optional, default friends)
- Party id (optional) (only used in user or betweenUs)
- Limit (optional)
- Before (optional)
- After (optional)
- lastTransactionID (optional) Response body:
{
"pagination": {
"lastTransactionID": Int // ID of last returned transaction
},
"data": [
{
"id": Int,
"balance": Double,
"amount": Double,
"action": String,
"status": String,
"note": String,
"dateCreated": Date,
"dateCompleted": Date,
"audience": String,
"actor": {
"id": Int,
"username": String,
"firstName": String,
"lastName": String,
"displayName": String,
},
"target": {
"id": Int,
"username": String,
"firstName": String,
"lastName": String,
"displayName": String,
}
},
{...},
...
]
}
Note: Venmo has removed its global feed for privacy reasons, and so will we.
GET /transactions/outstanding
Params:
- Session cookie
- Limit (optional)
- Before (optional)
- After (optional)
- lastTransactionID (optional)
{
"pagination": {
"lastTransactionID": Int // ID of last returned transaction[[]()]()
},
"data": [
{...},
...
]
}
GET /transaction/:transactionID
Params:
- Session cookie Response body:
{
"transaction": {...}
}
PUT /transaction/:transactionID
Params:
- Session cookie
- Action (approve, deny, cancel if sender) Response body:
{
"transaction: {...}
}