# Dokumentacja projektów (/projekty)
Każdy projekt ma tu własną część: opis, referencję API generowaną z kodu
i instrukcję podłączenia agenta AI przez MCP.
Wspólne przejazdy na festiwale w SzukamAndrzeja.pl.
## Dla agentów AI [#dla-agentów-ai]
- [`/llms.txt`](/llms.txt) — spis wszystkich stron z linkami do wersji markdown.
- [`/llms-full.txt`](/llms-full.txt) — cała dokumentacja w jednym pliku.
- `/mcp` — serwer MCP z narzędziami `search` i `execute`.
# Przejazdy (/projekty/przejazdy)
Przejazdy łączą kierowców i pasażerów jadących na ten sam festiwal. API obsługuje
przejazdy, rezerwacje miejsc, auta kierowców, czat, powiadomienia i opinie.
## Adres [#adres]
```
https://przejazdy.szukamandrzeja.pl
```
## Logowanie [#logowanie]
Operacje oznaczone kłódką wymagają sesji Better Auth, czyli ciasteczka
`__Secure-better-auth.session_token` z logowania w SzukamAndrzeja.pl.
Operacje publiczne (lista festiwali, wyszukiwarka, szczegóły przejazdu)
działają bez logowania.
## Skąd jest ta referencja [#skąd-jest-ta-referencja]
Referencja API powstaje z kontraktów oRPC w kodzie serwera. Plik
`server/docs/openapi.json` pilnują dwa testy, więc opis nie rozjeżdża się z tym,
co API naprawdę przyjmuje.
## Dla agentów AI [#dla-agentów-ai]
- [`/projekty/przejazdy/llms.txt`](/projekty/przejazdy/llms.txt) — cały projekt w markdownie.
- [Podłączenie przez MCP](/projekty/przejazdy/mcp) — wyszukiwanie i wywoływanie operacji.
# MCP (/projekty/przejazdy/mcp)
Serwer MCP pod `/mcp` ma dwa narzędzia, wspólne dla wszystkich projektów portalu:
- **`search`** — znajduje operacje po opisie („zarezerwuj miejsce”, „moje auta”)
i zwraca ich parametry oraz schemat treści żądania;
- **`execute`** — wywołuje wybraną operację po `operationId`.
Agent zawsze pyta najpierw `search`, a potem wywołuje `execute` z tym, co znalazł.
## Podłączenie [#podłączenie]
```bash
claude mcp add --transport http dokumentacja https:///mcp
```
## Działanie w imieniu użytkownika [#działanie-w-imieniu-użytkownika]
MCP nie ma własnych uprawnień. Operacje publiczne działają od razu. Do operacji
wymagających sesji klient podaje token sesji w nagłówku:
```bash
claude mcp add --transport http dokumentacja https:///mcp \
--header "Authorization: Bearer "
```
MCP przepisuje token do ciasteczka sesji i wysyła żądanie wyłącznie pod adres
API projektu. Agent może więc zrobić tylko to, co ten użytkownik w aplikacji.
## Czego MCP nie wywoła [#czego-mcp-nie-wywoła]
Webhooki wewnętrzne, endpoint diagnostyczny oraz strumienie (czat przez
WebSocket i powiadomienia przez SSE) są w referencji, ale `execute` ich nie obsługuje.
# Health check (/projekty/przejazdy/api/health/getPrzejazdyHealth)
### Health check
`GET /health` · operationId: `getPrzejazdyHealth`
Health probe returning operational status of przejazdy server.
**Odpowiedzi**
- `200` OK
# Informacje o buildzie (tylko IS_DEV) (/projekty/przejazdy/api/health/getPrzejazdyDebugInfo)
### Informacje o buildzie (tylko IS_DEV)
`GET /debug-info` · operationId: `getPrzejazdyDebugInfo`
Middleware zwraca 403, gdy IS_DEV !== 'true'; poza produkcją oddaje hash commita, gałąź i datę builda.
**Odpowiedzi**
- `200` Informacje o buildzie.
- `403` Trasa dostępna tylko w środowisku deweloperskim.
# List available rides (/projekty/przejazdy/api/rides/listPrzejazdyRides)
### List available rides
`GET /api/rides` · operationId: `listPrzejazdyRides`
Returns rides filtered by festival, date, route, and sorted as requested.
**Parametry**
- `cursor` (query): string
- `limit` (query): integer
- `festivalSlug` (query): string
- `direction` (query): string
- `status` (query): string
- `departureCity` (query): string
- `transportType` (query): string
- `dateFrom` (query): string
- `dateTo` (query): string
- `hasAvailableSeats` (query): boolean
- `maxCost` (query): number
- `sortBy` (query): string
**Odpowiedzi**
- `200` OK
# Create a new ride (/projekty/przejazdy/api/rides/createPrzejazdyRide)
### Create a new ride
`POST /api/rides` · operationId: `createPrzejazdyRide` · wymaga sesji
Creates a new ride for a festival. Author must be authenticated.
**Treść żądania** (wymagana)
```json
{
"type": "object",
"properties": {
"festivalSlug": {
"type": "string",
"minLength": 1
},
"direction": {
"enum": [
"to_festival",
"from_festival",
"both"
],
"type": "string"
},
"departureCity": {
"type": "string",
"minLength": 1
},
"departureAddress": {
"type": "string"
},
"departureLatitude": {
"type": "number",
"minimum": -90,
"maximum": 90
},
"departureLongitude": {
"type": "number",
"minimum": -180,
"maximum": 180
},
"departureDate": {
"type": "string",
"format": "date-time"
},
"stops": {
"type": "array",
"items": {
"type": "object",
"properties": {
"city": {
"type": "string",
"minLength": 1
},
"latitude": {
"type": "number",
"minimum": -90,
"maximum": 90
},
"longitude": {
"type": "number",
"minimum": -180,
"maximum": 180
},
"order": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"city",
"order"
]
},
"default": []
},
"transportType": {
"enum": [
"car",
"train",
"bus",
"van",
"other"
],
"type": "string"
},
"totalSeats": {
"type": "integer",
"minimum": 1,
"maximum": 8
},
"costPerPerson": {
"type": "number",
"minimum": 0
},
"costDescription": {
"type": "string",
"maxLength": 200
},
"carId": {
"type": "string"
},
"description": {
"type": "string",
"maxLength": 500
},
"luggageSpace": {
"enum": [
"small",
"medium",
"large",
"none"
],
"type": "string"
},
"petsAllowed": {
"type": "boolean",
"default": false
},
"smokingAllowed": {
"type": "boolean",
"default": false
},
"femaleOnly": {
"type": "boolean",
"default": false
}
},
"required": [
"festivalSlug",
"direction",
"departureCity",
"departureDate",
"transportType",
"totalSeats",
"costPerPerson",
"luggageSpace"
]
}
```
**Odpowiedzi**
- `201` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `429` Przekroczony limit żądań
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# List user rides (/projekty/przejazdy/api/rides/listPrzejazdyMyRides)
### List user rides
`GET /api/rides/me` · operationId: `listPrzejazdyMyRides` · wymaga sesji
Returns all rides created by the currently authenticated user.
**Parametry**
- `cursor` (query): string
- `limit` (query): integer
**Odpowiedzi**
- `200` OK
- `400` Niepoprawne dane wejściowe (domyślny kształt błędu walidatora)
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Get ride details (/projekty/przejazdy/api/rides/getPrzejazdyRide)
### Get ride details
`GET /api/rides/{id}` · operationId: `getPrzejazdyRide`
Returns full ride details including festival, car, author profile, and route stops.
**Parametry**
- `id` (path, wymagany): string
**Odpowiedzi**
- `200` OK
# Update ride (/projekty/przejazdy/api/rides/updatePrzejazdyRide)
### Update ride
`PUT /api/rides/{id}` · operationId: `updatePrzejazdyRide` · wymaga sesji
Updates ride details. Only ride author can update.
**Parametry**
- `id` (path, wymagany): string
**Treść żądania** (wymagana)
```json
{
"type": "object",
"properties": {
"festivalSlug": {
"type": "string",
"minLength": 1
},
"direction": {
"enum": [
"to_festival",
"from_festival",
"both"
],
"type": "string"
},
"departureCity": {
"type": "string",
"minLength": 1
},
"departureAddress": {
"type": "string"
},
"departureLatitude": {
"type": "number",
"minimum": -90,
"maximum": 90
},
"departureLongitude": {
"type": "number",
"minimum": -180,
"maximum": 180
},
"departureDate": {
"type": "string",
"format": "date-time"
},
"stops": {
"type": "array",
"items": {
"type": "object",
"properties": {
"city": {
"type": "string",
"minLength": 1
},
"latitude": {
"type": "number",
"minimum": -90,
"maximum": 90
},
"longitude": {
"type": "number",
"minimum": -180,
"maximum": 180
},
"order": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"city",
"order"
]
},
"default": []
},
"transportType": {
"enum": [
"car",
"train",
"bus",
"van",
"other"
],
"type": "string"
},
"totalSeats": {
"type": "integer",
"minimum": 1,
"maximum": 8
},
"costPerPerson": {
"type": "number",
"minimum": 0
},
"costDescription": {
"type": "string",
"maxLength": 200
},
"carId": {
"type": "string"
},
"description": {
"type": "string",
"maxLength": 500
},
"luggageSpace": {
"enum": [
"small",
"medium",
"large",
"none"
],
"type": "string"
},
"petsAllowed": {
"type": "boolean",
"default": false
},
"smokingAllowed": {
"type": "boolean",
"default": false
},
"femaleOnly": {
"type": "boolean",
"default": false
},
"status": {
"enum": [
"draft",
"active",
"full",
"completed",
"cancelled"
],
"type": "string"
}
}
}
```
**Odpowiedzi**
- `200` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Cancel ride (/projekty/przejazdy/api/rides/cancelPrzejazdyRide)
### Cancel ride
`PATCH /api/rides/{id}/cancel` · operationId: `cancelPrzejazdyRide` · wymaga sesji
Cancels an active ride and notifies passengers.
**Parametry**
- `id` (path, wymagany): string
**Odpowiedzi**
- `200` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Search rides, festivals, and users (/projekty/przejazdy/api/search/searchPrzejazdyRides)
### Search rides, festivals, and users
`GET /api/search` · operationId: `searchPrzejazdyRides`
Global search matching query string against festival names, ride departure cities, and user names.
**Parametry**
- `q` (query): string
- `limit` (query): integer
**Odpowiedzi**
- `200` OK
# List festivals (/projekty/przejazdy/api/festivals/listPrzejazdyFestivals)
### List festivals
`GET /api/festivals` · operationId: `listPrzejazdyFestivals`
Retrieves a list of festivals, optionally filtered by active status.
**Parametry**
- `activeOnly` (query): string
**Odpowiedzi**
- `200` OK
# Get festival details (/projekty/przejazdy/api/festivals/getPrzejazdyFestival)
### Get festival details
`GET /api/festivals/{slug}` · operationId: `getPrzejazdyFestival`
Returns festival details by slug.
**Parametry**
- `slug` (path, wymagany): string
**Odpowiedzi**
- `200` OK
# Platform stats (/projekty/przejazdy/api/stats/getPrzejazdyStats)
### Platform stats
`GET /api/stats` · operationId: `getPrzejazdyStats`
Returns platform metrics (total rides, active festivals, passenger seats).
**Odpowiedzi**
- `200` OK
# Get public user profile (/projekty/przejazdy/api/users/getPrzejazdyPublicUser)
### Get public user profile
`GET /api/users/{id}/public` · operationId: `getPrzejazdyPublicUser`
Returns public user profile, registered cars, and recent reviews.
**Parametry**
- `id` (path, wymagany): string
**Odpowiedzi**
- `200` OK
# List my reservations (/projekty/przejazdy/api/reservations/reservationsMine)
### List my reservations
`GET /api/reservations/me` · operationId: `reservationsMine` · wymaga sesji
Returns reservations of the currently authenticated user with ride details and driver contact only when the reservation is accepted.
**Parametry**
- `status` (query): string
- `cursor` (query): string
- `limit` (query): integer
**Odpowiedzi**
- `200` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# List reservations for a ride (/projekty/przejazdy/api/reservations/reservationsForRide)
### List reservations for a ride
`GET /api/reservations/ride/{rideId}` · operationId: `reservationsForRide` · wymaga sesji
Returns reservations for the given ride. Driver-only; passenger contact (phone) is exposed only for accepted reservations.
**Parametry**
- `rideId` (path, wymagany): string
- `cursor` (query): string
- `limit` (query): integer
**Odpowiedzi**
- `200` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Create reservation request (/projekty/przejazdy/api/reservations/reservationsCreate)
### Create reservation request
`POST /api/reservations` · operationId: `reservationsCreate` · wymaga sesji
Passenger requests seats on an active ride; reserves seats atomically, opens a conversation and notifies the driver.
**Treść żądania** (wymagana)
```json
{
"type": "object",
"properties": {
"rideId": {
"type": "string",
"minLength": 1
},
"seatsRequested": {
"type": "integer",
"minimum": 1,
"maximum": 4
},
"message": {
"type": "string",
"maxLength": 300
}
},
"required": [
"rideId",
"seatsRequested"
]
}
```
**Odpowiedzi**
- `200` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `429` Przekroczony limit żądań
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Respond to a reservation (/projekty/przejazdy/api/reservations/reservationsUpdateStatus)
### Respond to a reservation
`PATCH /api/reservations/{id}/status` · operationId: `reservationsUpdateStatus` · wymaga sesji
Driver accepts/rejects a pending reservation; passenger or driver cancels it. Seats are returned on reject/cancel.
**Parametry**
- `id` (path, wymagany): string
**Treść żądania** (wymagana)
```json
{
"type": "object",
"properties": {
"action": {
"enum": [
"accept",
"reject",
"cancel"
],
"type": "string"
}
},
"required": [
"action"
]
}
```
**Odpowiedzi**
- `200` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# List my cars (/projekty/przejazdy/api/cars/carsList)
### List my cars
`GET /api/cars` · operationId: `carsList` · wymaga sesji
Returns cars owned by the currently authenticated user (soft-deleted excluded).
**Odpowiedzi**
- `200` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Create a car (/projekty/przejazdy/api/cars/carsCreate)
### Create a car
`POST /api/cars` · operationId: `carsCreate` · wymaga sesji
Adds a car to the authenticated user garage.
**Treść żądania** (wymagana)
```json
{
"type": "object",
"properties": {
"brand": {
"type": "string",
"minLength": 1
},
"model": {
"type": "string",
"minLength": 1
},
"year": {
"type": "integer",
"minimum": 1950,
"maximum": 9007199254740991
},
"color": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"photoUrl": {
"anyOf": [
{
"anyOf": [
{
"type": "string",
"format": "uri"
},
{
"const": ""
}
]
},
{
"type": "null"
}
]
},
"doors": {
"anyOf": [
{
"type": "integer",
"minimum": 2,
"maximum": 10
},
{
"type": "null"
}
]
},
"seats": {
"anyOf": [
{
"type": "integer",
"minimum": 1,
"maximum": 20
},
{
"type": "null"
}
]
},
"bodyType": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"trunkCapacityLiters": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 10000
},
{
"type": "null"
}
]
}
},
"required": [
"brand",
"model",
"year"
]
}
```
**Odpowiedzi**
- `201` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Get my car (/projekty/przejazdy/api/cars/carsGet)
### Get my car
`GET /api/cars/{id}` · operationId: `carsGet` · wymaga sesji
Returns a garaged car by id. Only the owner can read it.
**Parametry**
- `id` (path, wymagany): string
**Odpowiedzi**
- `200` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Delete my car (/projekty/przejazdy/api/cars/carsDelete)
### Delete my car
`DELETE /api/cars/{id}` · operationId: `carsDelete` · wymaga sesji
Soft-deletes an owned car; refuses when the car is attached to active rides.
**Parametry**
- `id` (path, wymagany): string
**Odpowiedzi**
- `200` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Update my car (/projekty/przejazdy/api/cars/carsUpdate)
### Update my car
`PUT /api/cars/{id}` · operationId: `carsUpdate` · wymaga sesji
Updates an owned car. Missing fields stay untouched; empty strings clear nullable fields.
**Parametry**
- `id` (path, wymagany): string
**Treść żądania** (wymagana)
```json
{
"type": "object",
"properties": {
"brand": {
"type": "string",
"minLength": 1
},
"model": {
"type": "string",
"minLength": 1
},
"year": {
"type": "integer",
"minimum": 1950,
"maximum": 9007199254740991
},
"color": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"photoUrl": {
"anyOf": [
{
"anyOf": [
{
"type": "string",
"format": "uri"
},
{
"const": ""
}
]
},
{
"type": "null"
}
]
},
"doors": {
"anyOf": [
{
"type": "integer",
"minimum": 2,
"maximum": 10
},
{
"type": "null"
}
]
},
"seats": {
"anyOf": [
{
"type": "integer",
"minimum": 1,
"maximum": 20
},
{
"type": "null"
}
]
},
"bodyType": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"trunkCapacityLiters": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 10000
},
{
"type": "null"
}
]
}
}
}
```
**Odpowiedzi**
- `200` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Create a review (/projekty/przejazdy/api/reviews/reviewsCreate)
### Create a review
`POST /api/reviews` · operationId: `reviewsCreate` · wymaga sesji
Leaves a review for a counterpart of a completed ride and refreshes their average rating.
**Treść żądania** (wymagana)
```json
{
"type": "object",
"properties": {
"rideId": {
"type": "string",
"minLength": 1
},
"revieweeId": {
"type": "string",
"minLength": 1
},
"rating": {
"type": "integer",
"minimum": 1,
"maximum": 5
},
"comment": {
"type": "string",
"maxLength": 500
}
},
"required": [
"rideId",
"revieweeId",
"rating"
]
}
```
**Odpowiedzi**
- `201` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `429` Przekroczony limit żądań
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# List a user's reviews (/projekty/przejazdy/api/reviews/reviewsUser)
### List a user's reviews
`GET /api/reviews/user/{userId}` · operationId: `reviewsUser`
Returns public reviews received by the given user (no authentication required).
**Parametry**
- `userId` (path, wymagany): string
**Odpowiedzi**
- `200` OK
# List user conversations (/projekty/przejazdy/api/chat/chatList)
### List user conversations
`GET /api/chat` · operationId: `chatList` · wymaga sesji
Returns conversations of the authenticated user with unread counts.
**Odpowiedzi**
- `200` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Create conversation (/projekty/przejazdy/api/chat/chatCreate)
### Create conversation
`POST /api/chat` · operationId: `chatCreate` · wymaga sesji
Creates (or reuses) a conversation between the authenticated user and another ride participant.
**Treść żądania** (wymagana)
```json
{
"type": "object",
"properties": {
"otherUserId": {
"type": "string",
"minLength": 1
},
"rideId": {
"type": "string"
}
},
"required": [
"otherUserId"
]
}
```
**Odpowiedzi**
- `200` OK
- `400` Niepoprawne dane wejściowe (domyślny kształt błędu walidatora)
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `429` Przekroczony limit żądań
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# List conversation messages (/projekty/przejazdy/api/chat/chatMessagesList)
### List conversation messages
`GET /api/chat/{id}/messages` · operationId: `chatMessagesList` · wymaga sesji
Returns messages of a conversation the user participates in; newest page first pagination ascending.
**Parametry**
- `id` (path, wymagany): string
- `limit` (query): integer
- `cursor` (query): string
**Odpowiedzi**
- `200` OK
- `400` Niepoprawne dane wejściowe (domyślny kształt błędu walidatora)
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Send chat message (/projekty/przejazdy/api/chat/chatMessageCreate)
### Send chat message
`POST /api/chat/{id}/messages` · operationId: `chatMessageCreate` · wymaga sesji
Sends a message to a conversation the user participates in and notifies the recipient.
**Parametry**
- `id` (path, wymagany): string
**Treść żądania** (wymagana)
```json
{
"type": "object",
"properties": {
"content": {
"type": "string",
"minLength": 1,
"maxLength": 2000
}
},
"required": [
"content"
]
}
```
**Odpowiedzi**
- `200` OK
- `400` Niepoprawne dane wejściowe (domyślny kształt błędu walidatora)
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `429` Przekroczony limit żądań
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# WebSocket konwersacji (/projekty/przejazdy/api/chat/getPrzejazdyChatWs)
### WebSocket konwersacji
`GET /api/chat/{id}/ws` · operationId: `getPrzejazdyChatWs` · wymaga sesji
Przekazuje żądanie upgrade do Durable Object CHAT_DO (userId i conversationId jako parametry). Po sukcesie 101 Switching Protocols z ramkami JSON.
**Parametry**
- `id` (path, wymagany): string
**Odpowiedzi**
- `101` Przejście na protokół WebSocket (ramki JSON: message, messages_read).
- `401` Brak sesji (unauthorized)
- `403` Zalogowany użytkownik nie jest uczestnikiem konwersacji.
- `404` Konwersacja nie istnieje.
- `500` Błąd wewnętrzny.
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# List notifications (/projekty/przejazdy/api/notifications/notificationsList)
### List notifications
`GET /api/notifications` · operationId: `notificationsList` · wymaga sesji
Returns the latest 50 notifications of the authenticated user.
**Odpowiedzi**
- `200` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Mark notification as read (/projekty/przejazdy/api/notifications/notificationMarkRead)
### Mark notification as read
`PATCH /api/notifications/{id}/read` · operationId: `notificationMarkRead` · wymaga sesji
Marks a single notification of the authenticated user as read.
**Parametry**
- `id` (path, wymagany): string
**Odpowiedzi**
- `200` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Mark all notifications as read (/projekty/przejazdy/api/notifications/notificationsMarkAllRead)
### Mark all notifications as read
`PATCH /api/notifications/read-all` · operationId: `notificationsMarkAllRead` · wymaga sesji
Marks every unread notification of the authenticated user as read.
**Odpowiedzi**
- `200` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Strumień SSE licznika nieprzeczytanych (/projekty/przejazdy/api/notifications/streamPrzejazdyNotifications)
### Strumień SSE licznika nieprzeczytanych
`GET /api/notifications/stream` · operationId: `streamPrzejazdyNotifications` · wymaga sesji
Server-Sent Events: co 10 s zdarzenie `notification` z { unreadCount }.
**Odpowiedzi**
- `200` Strumień SSE (event: notification).
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Get own profile (/projekty/przejazdy/api/profile/profileMeGet)
### Get own profile
`GET /api/profile/me` · operationId: `profileMeGet` · wymaga sesji
Returns the profile of the authenticated user and their cars.
**Odpowiedzi**
- `200` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Update own profile (/projekty/przejazdy/api/profile/profileMeUpdate)
### Update own profile
`PATCH /api/profile/me` · operationId: `profileMeUpdate` · wymaga sesji
Updates bio and phone of the authenticated user profile.
**Treść żądania** (wymagana)
```json
{
"type": "object",
"properties": {
"bio": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"phone": {
"anyOf": [
{
"anyOf": [
{
"type": "string",
"pattern": "^(?:\\+?48[\\s-]?)?[1-9]\\d{2}[\\s-]?\\d{3}[\\s-]?\\d{3}$"
},
{
"const": ""
}
]
},
{
"type": "null"
}
]
}
}
}
```
**Odpowiedzi**
- `200` OK
- `400` Niepoprawne dane wejściowe (domyślny kształt błędu walidatora)
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# Create report (/projekty/przejazdy/api/reports/reportCreate)
### Create report
`POST /api/reports` · operationId: `reportCreate` · wymaga sesji
Reports a ride or a user to the moderation queue.
**Treść żądania** (wymagana)
```json
{
"type": "object",
"properties": {
"targetType": {
"enum": [
"ride",
"user"
],
"type": "string"
},
"targetId": {
"type": "string",
"minLength": 1
},
"reason": {
"type": "string",
"minLength": 5,
"maxLength": 1000
}
},
"required": [
"targetType",
"targetId",
"reason"
]
}
```
**Odpowiedzi**
- `201` OK
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `429` Przekroczony limit żądań
- `503` Serwer logowania chwilowo niedostępny (auth_unavailable)
# User deleted webhook (/projekty/przejazdy/api/webhooks/webhookUserDeleted)
### User deleted webhook
`POST /api/webhooks/auth/user-deleted` · operationId: `webhookUserDeleted`
Deletes every local record of a user removed from the auth service (bearer secret protected).
**Treść żądania** (wymagana)
```json
{
"type": "object",
"properties": {
"userId": {
"type": "string",
"minLength": 1
}
},
"required": [
"userId"
]
}
```
**Odpowiedzi**
- `200` OK
- `429` Przekroczony limit żądań
# Publiczny klucz VAPID (/projekty/przejazdy/api/push/getPrzejazdyVapidPublicKey)
### Publiczny klucz VAPID
`GET /api/push/vapid-public-key` · operationId: `getPrzejazdyVapidPublicKey`
Trasa publiczna; zwraca klucz publiczny albo 503, gdy push nie są skonfigurowane.
**Odpowiedzi**
- `200` Klucz publiczny VAPID.
# Zapisz subskrypcję push (/projekty/przejazdy/api/push/createPrzejazdyPushSubscription)
### Zapisz subskrypcję push
`POST /api/push/subscribe` · operationId: `createPrzejazdyPushSubscription` · wymaga sesji
Zapisuje/odświeża subskrypcję Web Push dla endpointu; konflikt, gdy endpoint należy do innego użytkownika.
**Treść żądania** (wymagana)
```json
{
"type": "object",
"properties": {
"endpoint": {
"type": "string",
"format": "uri"
},
"keys": {
"type": "object",
"properties": {
"p256dh": {
"type": "string"
},
"auth": {
"type": "string"
}
},
"required": [
"p256dh",
"auth"
]
}
},
"required": [
"endpoint",
"keys"
]
}
```
**Odpowiedzi**
- `200` Zapisano subskrypcję.
- `400` Niepoprawne dane wejściowe (domyślny kształt błędu walidatora)
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane
- `409` Endpoint należy do innego użytkownika (conflict).
# Usuń subskrypcję push (/projekty/przejazdy/api/push/deletePrzejazdyPushSubscription)
### Usuń subskrypcję push
`DELETE /api/push/unsubscribe` · operationId: `deletePrzejazdyPushSubscription` · wymaga sesji
Usuwa subskrypcję zalogowanego użytkownika dla podanego endpointu.
**Treść żądania** (wymagana)
```json
{
"type": "object",
"properties": {
"endpoint": {
"type": "string",
"format": "uri"
}
},
"required": [
"endpoint"
]
}
```
**Odpowiedzi**
- `200` Usunięto subskrypcję.
- `400` Niepoprawne dane wejściowe (domyślny kształt błędu walidatora)
- `401` Brak sesji (unauthorized)
- `403` Konto zablokowane