turniere-backend/doc/account_profiles_api.md

351 lines
6.2 KiB
Markdown

# Account Profiles And Team Players API
This API lets public pages show player account profiles and lets tournament
owners associate one or more player accounts with teams.
Terminology:
- account: existing `User` record
- player account: user account associated with one or more tournament teams
- tournament owner: organizer account that owns the tournament
- team player: account linked to a team through the `players` array
There is no separate organizer-only "create player" endpoint. Organizers create
or reuse player accounts by sending player email values through the tournament
or team endpoints below.
## Public Account Profile
Use this for public-facing player profile pages.
Endpoint:
- `GET /accounts/:id`
Authentication:
- optional
- anonymous callers see only public tournament/team profile data
- the account owner sees their own private tournament/team profile data too
Example response:
```json
{
"id": 42,
"name": "alice",
"username": "alice",
"tournaments": [
{
"id": 11,
"name": "Summer Cup",
"code": "a1b2c3",
"public": true
}
],
"created_tournaments": [
{
"id": 12,
"name": "Alice Open",
"code": "d4e5f6",
"public": true
}
],
"teams": [
{
"id": 99,
"name": "Team Alpha",
"tournament": {
"id": 11,
"name": "Summer Cup",
"code": "a1b2c3",
"public": true
}
}
]
}
```
Response fields:
- `id`: account id
- `name`: same value as `username`, for public display
- `username`: account username
- `tournaments`: tournaments where this account is linked to at least one team
- `created_tournaments`: tournaments created by this account
- `teams`: teams linked to this account
Visibility:
- anonymous/profile visitors see only public tournaments and teams in public tournaments
- authenticated profile owner sees public and private tournaments/teams for their own account
Errors:
- `404` when account id does not exist
## Team Read Payload
Teams expose linked player accounts in a `players` array.
Endpoint:
- `GET /teams/:id`
Example response:
```json
{
"id": 99,
"name": "Team Alpha",
"players": [
{
"id": 42,
"name": "alice",
"username": "alice"
},
{
"id": 43,
"name": "bob",
"username": "bob"
}
]
}
```
Empty team-player association:
```json
{
"id": 99,
"name": "Team Alpha",
"players": []
}
```
## Tournament Read Payload
Full tournament reads include the same player summaries on each team.
Endpoint:
- `GET /tournaments/:id`
Relevant response fragment:
```json
{
"id": 11,
"name": "Summer Cup",
"teams": [
{
"id": 99,
"name": "Team Alpha",
"players": [
{
"id": 42,
"name": "alice",
"username": "alice"
}
],
"advancing_from_group_stage": false
}
]
}
```
`GET /tournaments/:id?simple=true` does not include teams.
## Link Players While Creating Teams
Tournament creation accepts player email values inside new team objects.
Endpoint:
- `POST /tournaments`
Authentication:
- tournament owner account required
Single player:
```json
{
"name": "Summer Cup",
"public": true,
"teams": [
{
"name": "Team Alpha",
"player_email": "alice@example.com"
},
{
"name": "Team Beta"
}
]
}
```
Multiple players:
```json
{
"name": "Summer Cup",
"public": true,
"teams": [
{
"name": "Team Alpha",
"player_emails": [
"alice@example.com",
"bob@example.com"
]
}
]
}
```
Behavior:
- existing accounts are reused by case-insensitive email match
- missing accounts are created by email
- no password or token is returned for organizer-created accounts
- teams without player email values remain unlinked
- existing teams passed by `id` keep their existing player associations
Group-stage creation uses the same team object fields:
```json
{
"name": "Summer Cup",
"public": true,
"group_stage": true,
"playoff_teams_amount": 8,
"teams": [
{
"name": "Team Alpha",
"group": 0,
"player_emails": ["alice@example.com", "bob@example.com"]
}
]
}
```
## Link Or Replace Players On Existing Teams
Endpoint:
- `PATCH /teams/:id`
- `PUT /teams/:id`
Authentication:
- tournament owner may rename the team and manage player links
- linked player may rename their own team
- linked player may not change player links
- other authenticated users receive `403`
- read-only follower tournaments receive `423`
### Rename Team
```json
{
"name": "Team Alpha Renamed"
}
```
### Add One Player By Email
```json
{
"player_email": "alice@example.com"
}
```
Behavior:
- existing account is reused
- missing account is created
- player is appended to the team if not already linked
- existing team players stay linked
### Add One Player By Id
```json
{
"player_id": 42
}
```
Behavior:
- player is appended to the team if not already linked
- existing team players stay linked
- unknown id returns `404`
### Replace All Players By Email
```json
{
"player_emails": [
"alice@example.com",
"bob@example.com"
]
}
```
Behavior:
- replaces the full `players` list for the team
- empty array clears all players
- blank email values are ignored
- missing accounts are created
### Replace All Players By Id
```json
{
"player_ids": [42, 43]
}
```
Behavior:
- replaces the full `players` list for the team
- empty array clears all players
- unknown ids return `404`
### Clear All Players
Both single-value forms clear all players when sent blank:
```json
{
"player_email": ""
}
```
```json
{
"player_id": ""
}
```
## Error Handling
Expected statuses:
- `200` team/account read or team update accepted
- `201` tournament created
- `401` authentication required
- `403` authenticated user cannot change this team/tournament
- `404` account, team, tournament, or player id not found
- `422` invalid create/update payload
- `423` follower tournament is read-only
## Sync Behavior
Team-player account links are not part of leader/follower tournament sync
snapshots. Follower tournaments still expose teams, match data, and other synced
tournament data, but account ownership links are managed on the writable source
side.