feat: Add Steam account linking with team creation (#274)

## Description
<!-- Briefly describe the purpose and scope of your changes -->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a real-time Steam login flow using QR codes and server-sent
events (SSE) for team creation and authentication.
- Added Steam account and friend management, including secure credential
storage and friend list synchronization.
- Integrated Steam login endpoints into the API, enabling QR code-based
login and automated team setup.

- **Improvements**
- Enhanced data security by implementing encrypted storage for sensitive
tokens.
- Updated database schema to support Steam accounts, teams, memberships,
and social connections.
- Refined type definitions and consolidated account-related information
for improved consistency.

- **Bug Fixes**
  - Fixed trade ban status representation for Steam accounts.

- **Chores**
- Removed legacy C# Steam authentication service and related
configuration files.
  - Updated and cleaned up package dependencies and development tooling.
  - Streamlined type declaration files and resource definitions.

- **Style**
- Redesigned the team creation page UI with a modern, animated QR code
login interface.

- **Documentation**
  - Updated OpenAPI documentation for new Steam login endpoints.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Wanjohi
2025-05-09 01:13:44 +03:00
committed by GitHub
parent 70d629227a
commit 7e69af977b
51 changed files with 2332 additions and 2805 deletions

View File

@@ -0,0 +1,651 @@
{
"id": "56a4d60a-c062-47e5-a97e-625443411ad8",
"prevId": "1717c769-cee0-4242-bcbb-9538c80d985c",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.steam_account_credentials": {
"name": "steam_account_credentials",
"schema": "",
"columns": {
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_updated": {
"name": "time_updated",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"steam_id": {
"name": "steam_id",
"type": "varchar(255)",
"primaryKey": true,
"notNull": true
},
"refresh_token": {
"name": "refresh_token",
"type": "text",
"primaryKey": false,
"notNull": true
},
"expiry": {
"name": "expiry",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true
},
"username": {
"name": "username",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"steam_account_credentials_steam_id_steam_accounts_steam_id_fk": {
"name": "steam_account_credentials_steam_id_steam_accounts_steam_id_fk",
"tableFrom": "steam_account_credentials",
"tableTo": "steam_accounts",
"columnsFrom": [
"steam_id"
],
"columnsTo": [
"steam_id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.friends_list": {
"name": "friends_list",
"schema": "",
"columns": {
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_updated": {
"name": "time_updated",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"steam_id": {
"name": "steam_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"friend_steam_id": {
"name": "friend_steam_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"friends_list_steam_id_steam_accounts_steam_id_fk": {
"name": "friends_list_steam_id_steam_accounts_steam_id_fk",
"tableFrom": "friends_list",
"tableTo": "steam_accounts",
"columnsFrom": [
"steam_id"
],
"columnsTo": [
"steam_id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"friends_list_friend_steam_id_steam_accounts_steam_id_fk": {
"name": "friends_list_friend_steam_id_steam_accounts_steam_id_fk",
"tableFrom": "friends_list",
"tableTo": "steam_accounts",
"columnsFrom": [
"friend_steam_id"
],
"columnsTo": [
"steam_id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"friends_list_steam_id_friend_steam_id_pk": {
"name": "friends_list_steam_id_friend_steam_id_pk",
"columns": [
"steam_id",
"friend_steam_id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.members": {
"name": "members",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "char(30)",
"primaryKey": false,
"notNull": true
},
"team_id": {
"name": "team_id",
"type": "char(30)",
"primaryKey": false,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_updated": {
"name": "time_updated",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"user_id": {
"name": "user_id",
"type": "char(30)",
"primaryKey": false,
"notNull": false
},
"steam_id": {
"name": "steam_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"role": {
"name": "role",
"type": "member_role",
"typeSchema": "public",
"primaryKey": false,
"notNull": true
}
},
"indexes": {
"idx_member_steam_id": {
"name": "idx_member_steam_id",
"columns": [
{
"expression": "team_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "steam_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
},
"idx_member_user_id": {
"name": "idx_member_user_id",
"columns": [
{
"expression": "team_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "user_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"where": "\"members\".\"user_id\" is not null",
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"members_user_id_users_id_fk": {
"name": "members_user_id_users_id_fk",
"tableFrom": "members",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"members_steam_id_steam_accounts_steam_id_fk": {
"name": "members_steam_id_steam_accounts_steam_id_fk",
"tableFrom": "members",
"tableTo": "steam_accounts",
"columnsFrom": [
"steam_id"
],
"columnsTo": [
"steam_id"
],
"onDelete": "cascade",
"onUpdate": "restrict"
}
},
"compositePrimaryKeys": {
"members_id_team_id_pk": {
"name": "members_id_team_id_pk",
"columns": [
"id",
"team_id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.steam_accounts": {
"name": "steam_accounts",
"schema": "",
"columns": {
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_updated": {
"name": "time_updated",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"steam_id": {
"name": "steam_id",
"type": "varchar(255)",
"primaryKey": true,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "char(30)",
"primaryKey": false,
"notNull": false
},
"status": {
"name": "status",
"type": "steam_status",
"typeSchema": "public",
"primaryKey": false,
"notNull": true
},
"last_synced_at": {
"name": "last_synced_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true
},
"real_name": {
"name": "real_name",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"member_since": {
"name": "member_since",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"profile_url": {
"name": "profile_url",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
},
"username": {
"name": "username",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"avatar_hash": {
"name": "avatar_hash",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"limitations": {
"name": "limitations",
"type": "json",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"steam_accounts_user_id_users_id_fk": {
"name": "steam_accounts_user_id_users_id_fk",
"tableFrom": "steam_accounts",
"tableTo": "users",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"idx_steam_username": {
"name": "idx_steam_username",
"nullsNotDistinct": false,
"columns": [
"username"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.teams": {
"name": "teams",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "char(30)",
"primaryKey": true,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_updated": {
"name": "time_updated",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"name": {
"name": "name",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"owner_id": {
"name": "owner_id",
"type": "char(30)",
"primaryKey": false,
"notNull": true
},
"invite_code": {
"name": "invite_code",
"type": "varchar(10)",
"primaryKey": false,
"notNull": true
},
"slug": {
"name": "slug",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"max_members": {
"name": "max_members",
"type": "bigint",
"primaryKey": false,
"notNull": true
}
},
"indexes": {
"idx_team_slug": {
"name": "idx_team_slug",
"columns": [
{
"expression": "slug",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"teams_owner_id_users_id_fk": {
"name": "teams_owner_id_users_id_fk",
"tableFrom": "teams",
"tableTo": "users",
"columnsFrom": [
"owner_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"teams_slug_steam_accounts_username_fk": {
"name": "teams_slug_steam_accounts_username_fk",
"tableFrom": "teams",
"tableTo": "steam_accounts",
"columnsFrom": [
"slug"
],
"columnsTo": [
"username"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"idx_team_invite_code": {
"name": "idx_team_invite_code",
"nullsNotDistinct": false,
"columns": [
"invite_code"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.users": {
"name": "users",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "char(30)",
"primaryKey": true,
"notNull": true
},
"time_created": {
"name": "time_created",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_updated": {
"name": "time_updated",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"time_deleted": {
"name": "time_deleted",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"email": {
"name": "email",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"avatar_url": {
"name": "avatar_url",
"type": "text",
"primaryKey": false,
"notNull": false
},
"last_login": {
"name": "last_login",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"polar_customer_id": {
"name": "polar_customer_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"idx_user_email": {
"name": "idx_user_email",
"nullsNotDistinct": false,
"columns": [
"email"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {
"public.member_role": {
"name": "member_role",
"schema": "public",
"values": [
"child",
"adult"
]
},
"public.steam_status": {
"name": "steam_status",
"schema": "public",
"values": [
"online",
"offline",
"dnd",
"playing"
]
}
},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}

View File

@@ -71,6 +71,13 @@
"when": 1744651817581,
"tag": "0009_luxuriant_wraith",
"breakpoints": true
},
{
"idx": 10,
"version": "7",
"when": 1746726715456,
"tag": "0010_certain_dust",
"breakpoints": true
}
]
}