Skip to content

Commit 864195e

Browse files
authored
Merge pull request #10 from PFConnect/main
Added vatsim rating display
2 parents 783bb80 + e5ee6ed commit 864195e

10 files changed

Lines changed: 571 additions & 24 deletions

File tree

.env.example

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,9 @@ JWT_SECRET=
1414
CEPHIE_API_KEY=
1515

1616
DEBUG=true
17-
PORT=9901
17+
PORT=9901
18+
19+
# VATSIM OAuth
20+
VATSIM_CLIENT_ID=
21+
VATSIM_CLIENT_SECRET=
22+
VATSIM_REDIRECT_URI=http://localhost:5173/login/vatsim/callback

public/assets/images/vatsim.svg

Lines changed: 11 additions & 0 deletions
Loading

server/db/logbook.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,11 @@ export async function getPublicPilotProfile(username) {
10441044
u.discriminator,
10451045
u.avatar,
10461046
u.roblox_username,
1047+
u.roblox_user_id,
1048+
u.vatsim_cid,
1049+
u.vatsim_rating_id,
1050+
u.vatsim_rating_short,
1051+
u.vatsim_rating_long,
10471052
u.created_at
10481053
FROM users u
10491054
WHERE LOWER(u.username) = LOWER($1)
@@ -1055,6 +1060,16 @@ export async function getPublicPilotProfile(username) {
10551060

10561061
const user = userResult.rows[0];
10571062

1063+
// Fallback: derive short rating from numeric id if not stored as text
1064+
let vatsimShort = user.vatsim_rating_short;
1065+
if (!vatsimShort && (typeof user.vatsim_rating_id === 'number' || typeof user.vatsim_rating_id === 'string')) {
1066+
const ratingIdNum = typeof user.vatsim_rating_id === 'number' ? user.vatsim_rating_id : parseInt(user.vatsim_rating_id, 10);
1067+
const map = { 0: 'OBS', 1: 'S1', 2: 'S2', 3: 'S3', 4: 'C1', 5: 'C2', 6: 'C3', 7: 'I1', 8: 'I2', 9: 'I3', 10: 'SUP', 11: 'ADM' };
1068+
if (Number.isFinite(ratingIdNum) && Object.prototype.hasOwnProperty.call(map, ratingIdNum)) {
1069+
vatsimShort = map[ratingIdNum];
1070+
}
1071+
}
1072+
10581073
const rolesResult = await pool.query(`
10591074
SELECT r.id, r.name, r.description, r.color, r.icon, r.priority
10601075
FROM roles r
@@ -1102,6 +1117,10 @@ export async function getPublicPilotProfile(username) {
11021117
discriminator: user.discriminator,
11031118
avatar: user.avatar,
11041119
roblox_username: user.roblox_username,
1120+
roblox_user_id: user.roblox_user_id,
1121+
vatsim_cid: user.vatsim_cid,
1122+
vatsim_rating_short: vatsimShort,
1123+
vatsim_rating_long: user.vatsim_rating_long,
11051124
member_since: user.created_at,
11061125
is_admin: isAdmin(user.id),
11071126
roles: rolesResult.rows,

server/db/users.js

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,21 @@ async function initializeUsersTable() {
3030
settings_updated_at TIMESTAMP DEFAULT NOW(),
3131
total_sessions_created INTEGER DEFAULT 0,
3232
total_minutes INTEGER DEFAULT 0,
33+
-- VATSIM linkage
34+
vatsim_cid VARCHAR(16),
35+
vatsim_rating_id INTEGER,
36+
vatsim_rating_short VARCHAR(8),
37+
vatsim_rating_long VARCHAR(32),
3338
created_at TIMESTAMP DEFAULT NOW(),
3439
updated_at TIMESTAMP DEFAULT NOW()
3540
)
3641
`);
42+
} else {
43+
// Ensure VATSIM columns exist on existing installations
44+
await pool.query("ALTER TABLE users ADD COLUMN IF NOT EXISTS vatsim_cid VARCHAR(16)");
45+
await pool.query("ALTER TABLE users ADD COLUMN IF NOT EXISTS vatsim_rating_id INTEGER");
46+
await pool.query("ALTER TABLE users ADD COLUMN IF NOT EXISTS vatsim_rating_short VARCHAR(8)");
47+
await pool.query("ALTER TABLE users ADD COLUMN IF NOT EXISTS vatsim_rating_long VARCHAR(32)");
3748
}
3849
} catch (error) {
3950
console.error('Error initializing users table:', error);
@@ -310,7 +321,12 @@ export async function getUserById(id) {
310321
roleName: user.role_name,
311322
rolePermissions: rolePermissions,
312323
robloxUserId: user.roblox_user_id,
313-
robloxUsername: user.roblox_username
324+
robloxUsername: user.roblox_username,
325+
// VATSIM linkage
326+
vatsimCid: user.vatsim_cid,
327+
vatsimRatingId: user.vatsim_rating_id,
328+
vatsimRatingShort: user.vatsim_rating_short,
329+
vatsimRatingLong: user.vatsim_rating_long
314330
};
315331
} catch (error) {
316332
console.error('Error fetching user:', error);
@@ -406,6 +422,44 @@ export async function unlinkRobloxAccount(userId) {
406422
}
407423
}
408424

425+
export async function updateVatsimAccount(userId, { vatsimCid, ratingId, ratingShort, ratingLong }) {
426+
try {
427+
await pool.query(`
428+
UPDATE users SET
429+
vatsim_cid = $2,
430+
vatsim_rating_id = $3,
431+
vatsim_rating_short = $4,
432+
vatsim_rating_long = $5,
433+
updated_at = NOW()
434+
WHERE id = $1
435+
`, [userId, vatsimCid, ratingId, ratingShort, ratingLong]);
436+
437+
return await getUserById(userId);
438+
} catch (error) {
439+
console.error('Error updating VATSIM account:', error);
440+
throw error;
441+
}
442+
}
443+
444+
export async function unlinkVatsimAccount(userId) {
445+
try {
446+
await pool.query(`
447+
UPDATE users SET
448+
vatsim_cid = NULL,
449+
vatsim_rating_id = NULL,
450+
vatsim_rating_short = NULL,
451+
vatsim_rating_long = NULL,
452+
updated_at = NOW()
453+
WHERE id = $1
454+
`, [userId]);
455+
456+
return await getUserById(userId);
457+
} catch (error) {
458+
console.error('Error unlinking VATSIM account:', error);
459+
throw error;
460+
}
461+
}
462+
409463
initializeUsersTable();
410464

411-
export { initializeUsersTable };
465+
export { initializeUsersTable };

0 commit comments

Comments
 (0)