readme and db updates

trunk
Adam Veldhousen 3 years ago
parent f129d5338d
commit 375193f9f4
Signed by: adam
GPG Key ID: 6DB29003C6DD1E4B

@ -1,3 +1,34 @@
# Body track # Body track
[![Build Status](https://ci.vdhsn.com/api/badges/adam/bodytrack/status.svg?ref=refs/heads/trunk)](https://ci.vdhsn.com/adam/bodytrack) [![Build Status](https://ci.vdhsn.com/api/badges/adam/bodytrack/status.svg?ref=refs/heads/trunk)](https://ci.vdhsn.com/adam/bodytrack)
## Body track backend rules
- Database commandments
1. All measurement values are in metric units
- weight = kg
- height = cm
- calories = kcal
2. All time values are in UTC
3. All ip related values need to support both ipv4 and ipv6
4. Email addresses are unique per user
- HTTP APIs specs
- Authentication
- JWTs:
- 14 day maximum lease time
- claims (userid)
- OAuth2: scopes (email, profile, stats, workouts)
- REST based design
- Allow export via CSV all personal data
- Allow deleting account data
- 80ms 95th percentile max response time for all calls
- Frontend specs
- Support Chrome, Firefox, Safari
- Support mobile and desktop sizes
- All pages should be bookmarkable, including queries for charts and search
- Performance
- 2 seconds 95th pct for TTI
- Full page size must be under 500kb (including API calls)

@ -15,12 +15,12 @@ start: .data
-u $$UID:$$UID \ -u $$UID:$$UID \
postgres:13-alpine postgres:13-alpine
logs:
docker logs bodytrack-db
stop: stop:
@docker rm -f -v bodytrack-db @docker rm -f -v bodytrack-db
logs:
docker logs bodytrack-db
.PHONY: clean default start stop .PHONY: clean default start stop
.data: .data:

@ -1 +1,3 @@
CREATE TYPE UNIT AS ENUM ('Metric', 'Imperial'); CREATE TYPE UNIT AS ENUM ('Metric', 'Imperial');
CREATE TYPE LogType AS ENUM ('Weight', 'Height', 'Calories');

@ -4,27 +4,27 @@ CREATE TABLE Accounts.Users (
id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
email VARCHAR(128) NOT NULL UNIQUE, email VARCHAR(128) NOT NULL UNIQUE,
emailVerificationTs TIMESTAMP DEFAULT NULL, emailVerificationTs TIMESTAMP DEFAULT NULL,
passwordHash VARCHAR(512) NOT NULL emailVerificationCode VARCHAR(128),
passwordHash VARCHAR(512) NOT NULL,
passwordResetCode VARCHAR(128)
); );
CREATE TABLE Accounts.Profile ( CREATE TABLE Accounts.Profile (
userId INT NOT NULL REFERENCES Accounts.Users(id), userId INT NOT NULL REFERENCES Accounts.Users(id),
username VARCHAR(64) NOT NULL, username VARCHAR(64) NOT NULL,
birthdate TIMESTAMP NOT NULL, birthdate TIMESTAMP NOT NULL,
height DECIMAL NOT NULL, height DECIMAL NOT NULL,
displayUnit UNIT NOT NULL displayUnit UNIT NOT NULL DEFAULT 'Metric'
); );
CREATE INDEX profile_userid ON Accounts.Profile USING btree (userId);
CREATE TABLE Accounts.UsersAuth ( CREATE TABLE Accounts.UsersAuth (
userId INT NOT NULL REFERENCES Accounts.Users(id), userId INT NOT NULL REFERENCES Accounts.Users(id),
tokenHash VARCHAR(512) NOT NULL, tokenHash VARCHAR(512) NOT NULL,
device VARCHAR(64) NOT NULL, deviceId VARCHAR(64) NOT NULL,
createdTs TIMESTAMP DEFAULT NOW(), createdTs TIMESTAMP DEFAULT NOW(),
sourceIp VARCHAR(32) DEFAULT NULL sourceIp VARCHAR(32) DEFAULT NULL
); );
CREATE INDEX usersauth_userid ON Accounts.UsersAuth USING btree (userId);

@ -1,11 +1,22 @@
CREATE SCHEMA Stats; CREATE SCHEMA Stats;
CREATE TABLE Stats.WeightLog ( CREATE TABLE Stats.Log (
id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
userId INT NOT NULL REFERENCES Accounts.Users(id), userId INT NOT NULL REFERENCES Accounts.Users(id),
logType LogType NOT NULL DEFAULT 'Weight',
value DECIMAL NOT NULL, value DECIMAL NOT NULL,
recordedTs TIMESTAMP NOT NULL DEFAULT NOW() recordedTs TIMESTAMP NOT NULL DEFAULT NOW()
); );
CREATE INDEX weightlog_userId ON stats.weightlog USING btree (userId); CREATE INDEX log_logType ON Stats.Log USING btree (logType);
CREATE TABLE Stats.LogGoal (
id SERIAL PRIMARY KEY,
userId INT NOT NULL REFERENCES Accounts.Users(id),
logType LogType NOT NULL,
value DECIMAL NOT NULL,
startTs TIMESTAMP NOT NULL DEFAULT NOW(),
endTs TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE INDEX log_userId ON Stats.LogGoal USING btree (userId);

@ -1,15 +1,54 @@
INSERT INTO Accounts.Users(email, emailVerificationTs, passwordHash) VALUES ('adam@vdhsn.com', NOW(), 'JDJhJDA0JDlMdVRFek9SQi92RGxucXpYOVZkRWVSQXphR2R2VGZPZGJvYWNMeDhZM2NmUkFRaVFUYkpP'); INSERT INTO Accounts.Users(email, emailVerificationTs, passwordHash) VALUES ('adam@vdhsn.com', NOW(), 'JDJhJDA0JDlMdVRFek9SQi92RGxucXpYOVZkRWVSQXphR2R2VGZPZGJvYWNMeDhZM2NmUkFRaVFUYkpP');
INSERT INTO Accounts.Users(email, emailVerificationTs, passwordHash) VALUES ('adam@example.com', NULL, 'JDJhJDA0JDlMdVRFek9SQi92RGxucXpYOVZkRWVSQXphR2R2VGZPZGJvYWNMeDhZM2NmUkFRaVFUYkpP'); INSERT INTO Accounts.Users(email, emailVerificationTs, passwordHash) VALUES ('adam@example.com', NULL, 'JDJhJDA0JDlMdVRFek9SQi92RGxucXpYOVZkRWVSQXphR2R2VGZPZGJvYWNMeDhZM2NmUkFRaVFUYkpP');
INSERT INTO Accounts.Profile (userId, username, birthdate, height, displayUnit) INSERT INTO Accounts.Profile (userId, username, birthdate, height, displayUnit)
VALUES (1, 'adam', '1990-09-28 5:23:54', 182.88, 'Imperial'); VALUES (1, 'adam', '1990-09-28 5:23:54', 77.1107, 'Imperial');
INSERT INTO Accounts.Profile (userId, username, birthdate, height, displayUnit) INSERT INTO Accounts.Profile (userId, username, birthdate, height, displayUnit)
VALUES (2, 'adam', '1990-09-28 5:23:54', 182.88, 'Imperial'); VALUES (2, 'adam', '1990-09-28 5:23:54', 77.1107, 'Imperial');
INSERT INTO Stats.WeightLog (userId, value) VALUES (1, 77.1107); INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 77.1107, '2020-02-01 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 76.1107, '2020-02-02 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 78.1107, '2020-02-03 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 79.1107, '2020-02-04 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 77.1107, '2020-02-07 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 76.1107, '2020-02-12 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 75.1107, '2020-02-18 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 73.1107, '2020-02-22 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 72.1107, '2020-02-27 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 74.1107, '2020-03-01 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 76.1107, '2020-03-02 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 78.1107, '2020-03-03 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 79.1107, '2020-03-04 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 77.1107, '2020-03-07 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 76.1107, '2020-03-12 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 75.1107, '2020-03-18 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 73.1107, '2020-03-27 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 72.1107, '2020-03-30 00:00:00');
INSERT INTO Stats.Log (userId, logType, value, recordedTs)
VALUES (1, 'Weight', 71.1107, '2020-04-04 00:00:00');
INSERT INTO Stats.LogGoal (userId, logType, value, endTs, startTs)
VALUES (1, 'Weight', 70, '2020-06-01 00:00:00', '2020-01-01 00:00:00');

@ -4,7 +4,6 @@ start: start-client start-api start-db
stop: stop-api stop-db stop: stop-api stop-db
start-db: start-db:
cd db && $(MAKE) start cd db && $(MAKE) start

Loading…
Cancel
Save