Skip to content

Commit 1066766

Browse files
authored
Merge pull request #1628 from dsdhananjay22/feat/oss-four-issues
Feat/oss four issues
2 parents b8ee99c + 08d94ac commit 1066766

26 files changed

Lines changed: 4338 additions & 216 deletions

API.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,7 @@ available price contributes zero to `total_value_usd` rather than being assumed.
496496
- **POST /api/portfolio/{id}/rebalance** — Execute rebalance (body optional: `{ options: { simulateOnly, ignoreSafetyChecks, slippageOverrides } }`). Supports `Idempotency-Key`.
497497
- **GET /api/portfolio/{id}/analytics** — Analytics time series (query: `days`, default 30).
498498
- **GET /api/portfolio/{id}/performance-summary** — Performance summary.
499+
- **GET /api/portfolio/tax-report** — Realized gain/loss tax report computed with FIFO cost basis (query: `year` optional, defaults to current year; `format` `json` (default) or `csv`).
499500
500501
Response:
501502
```json
@@ -997,6 +998,10 @@ GET /api/v1/assets/{symbol}
997998
998999
## Notifications
9991000
1001+
- **GET /api/notifications/alerts/thresholds** — Get per-asset price alert threshold overrides and the global default for a user (query: `userId`, required).
1002+
- **PUT /api/notifications/alerts/thresholds** — Merge per-asset price alert threshold overrides for a user (body: `userId`, `thresholds`).
1003+
- **DELETE /api/notifications/alerts/thresholds** — Remove a single per-asset price alert threshold override (query: `userId`, `asset`, both required).
1004+
10001005
### Subscribe
10011006
10021007
```bash
@@ -1033,6 +1038,47 @@ DELETE /api/v1/notifications/unsubscribe?userId=GALPHABET...&reason=no-longer-ne
10331038
GET /api/v1/notifications/logs?userId=GALPHABET...
10341039
```
10351040
1041+
### Get Price Alert Thresholds
1042+
1043+
```bash
1044+
GET /api/v1/notifications/alerts/thresholds?userId=GALPHABET...
1045+
```
1046+
1047+
Returns per-asset price alert threshold overrides and the user's global default:
1048+
1049+
```json
1050+
{
1051+
"success": true,
1052+
"data": {
1053+
"thresholds": { "XLM": 7, "BTC": 3 },
1054+
"defaultThreshold": 5
1055+
},
1056+
"timestamp": "2025-01-01T00:00:00.000Z"
1057+
}
1058+
```
1059+
1060+
### Set Price Alert Thresholds
1061+
1062+
```bash
1063+
PUT /api/v1/notifications/alerts/thresholds
1064+
Content-Type: application/json
1065+
1066+
{
1067+
"userId": "GALPHABET...",
1068+
"thresholds": { "XLM": 7, "BTC": 3 }
1069+
}
1070+
```
1071+
1072+
Merges the provided per-asset overrides into the user's existing overrides.
1073+
1074+
### Delete a Price Alert Threshold
1075+
1076+
```bash
1077+
DELETE /api/v1/notifications/alerts/thresholds?userId=GALPHABET...&asset=XLM
1078+
```
1079+
1080+
Removes the per-asset override for the given asset so alert evaluation falls back to the user's global default.
1081+
10361082
---
10371083
10381084
## Consent (GDPR)

backend/openapi.json

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1752,6 +1752,81 @@
17521752
}
17531753
}
17541754
},
1755+
"/api/portfolio/tax-report": {
1756+
"get": {
1757+
"tags": [
1758+
"Portfolio"
1759+
],
1760+
"summary": "Get tax report",
1761+
"description": "Realized gain/loss tax report computed with FIFO cost basis for a tax year.",
1762+
"parameters": [
1763+
{
1764+
"name": "year",
1765+
"in": "query",
1766+
"schema": {
1767+
"type": "integer",
1768+
"minimum": 2000,
1769+
"maximum": 2100,
1770+
"description": "Tax year (defaults to the current year)"
1771+
}
1772+
},
1773+
{
1774+
"name": "format",
1775+
"in": "query",
1776+
"schema": {
1777+
"type": "string",
1778+
"enum": [
1779+
"json",
1780+
"csv"
1781+
],
1782+
"default": "json"
1783+
}
1784+
}
1785+
],
1786+
"responses": {
1787+
"200": {
1788+
"description": "Tax report summary (JSON) or CSV download (format=csv)",
1789+
"content": {
1790+
"application/json": {
1791+
"schema": {
1792+
"$ref": "#/components/schemas/ApiEnvelope"
1793+
}
1794+
},
1795+
"text/csv": {
1796+
"schema": {
1797+
"type": "string"
1798+
}
1799+
}
1800+
}
1801+
},
1802+
"400": {
1803+
"description": "Invalid year",
1804+
"content": {
1805+
"application/json": {
1806+
"schema": {
1807+
"$ref": "#/components/schemas/ApiError"
1808+
},
1809+
"examples": {
1810+
"ValidationError": {
1811+
"$ref": "#/components/examples/ValidationError"
1812+
}
1813+
}
1814+
}
1815+
}
1816+
},
1817+
"500": {
1818+
"description": "Internal error",
1819+
"content": {
1820+
"application/json": {
1821+
"schema": {
1822+
"$ref": "#/components/schemas/ApiError"
1823+
}
1824+
}
1825+
}
1826+
}
1827+
}
1828+
}
1829+
},
17551830
"/api/risk/metrics/{portfolioId}": {
17561831
"get": {
17571832
"tags": [
@@ -2862,6 +2937,210 @@
28622937
}
28632938
}
28642939
},
2940+
"/api/notifications/alerts/thresholds": {
2941+
"get": {
2942+
"tags": [
2943+
"Notifications"
2944+
],
2945+
"summary": "Get price alert thresholds",
2946+
"description": "Get per-asset price alert threshold overrides and the global default threshold for a user.",
2947+
"parameters": [
2948+
{
2949+
"name": "userId",
2950+
"in": "query",
2951+
"required": true,
2952+
"schema": {
2953+
"type": "string"
2954+
}
2955+
}
2956+
],
2957+
"responses": {
2958+
"200": {
2959+
"description": "Alert thresholds",
2960+
"content": {
2961+
"application/json": {
2962+
"schema": {
2963+
"$ref": "#/components/schemas/ApiEnvelope"
2964+
}
2965+
}
2966+
}
2967+
},
2968+
"400": {
2969+
"description": "userId required",
2970+
"content": {
2971+
"application/json": {
2972+
"schema": {
2973+
"$ref": "#/components/schemas/ApiError"
2974+
},
2975+
"examples": {
2976+
"QueryValidationError": {
2977+
"$ref": "#/components/examples/QueryValidationError"
2978+
}
2979+
}
2980+
}
2981+
}
2982+
},
2983+
"500": {
2984+
"description": "Internal error",
2985+
"content": {
2986+
"application/json": {
2987+
"schema": {
2988+
"$ref": "#/components/schemas/ApiError"
2989+
}
2990+
}
2991+
}
2992+
}
2993+
}
2994+
},
2995+
"put": {
2996+
"tags": [
2997+
"Notifications"
2998+
],
2999+
"summary": "Set price alert thresholds",
3000+
"description": "Set or merge per-asset price alert threshold overrides for a user.",
3001+
"requestBody": {
3002+
"required": true,
3003+
"content": {
3004+
"application/json": {
3005+
"schema": {
3006+
"type": "object",
3007+
"required": [
3008+
"thresholds"
3009+
],
3010+
"properties": {
3011+
"userId": {
3012+
"type": "string",
3013+
"description": "Required when auth is disabled"
3014+
},
3015+
"thresholds": {
3016+
"type": "object",
3017+
"additionalProperties": {
3018+
"type": "number",
3019+
"minimum": 1
3020+
},
3021+
"description": "Map of asset code to threshold percentage",
3022+
"example": {
3023+
"XLM": 7,
3024+
"BTC": 3
3025+
}
3026+
}
3027+
}
3028+
}
3029+
}
3030+
}
3031+
},
3032+
"responses": {
3033+
"200": {
3034+
"description": "Updated alert thresholds",
3035+
"content": {
3036+
"application/json": {
3037+
"schema": {
3038+
"$ref": "#/components/schemas/ApiEnvelope"
3039+
}
3040+
}
3041+
}
3042+
},
3043+
"400": {
3044+
"description": "Validation error",
3045+
"content": {
3046+
"application/json": {
3047+
"schema": {
3048+
"$ref": "#/components/schemas/ApiError"
3049+
},
3050+
"examples": {
3051+
"ValidationError": {
3052+
"$ref": "#/components/examples/ValidationError"
3053+
}
3054+
}
3055+
}
3056+
}
3057+
},
3058+
"500": {
3059+
"description": "Internal error",
3060+
"content": {
3061+
"application/json": {
3062+
"schema": {
3063+
"$ref": "#/components/schemas/ApiError"
3064+
}
3065+
}
3066+
}
3067+
}
3068+
}
3069+
},
3070+
"delete": {
3071+
"tags": [
3072+
"Notifications"
3073+
],
3074+
"summary": "Delete price alert threshold",
3075+
"description": "Remove a single per-asset price alert threshold override for a user.",
3076+
"parameters": [
3077+
{
3078+
"name": "userId",
3079+
"in": "query",
3080+
"required": true,
3081+
"schema": {
3082+
"type": "string"
3083+
}
3084+
},
3085+
{
3086+
"name": "asset",
3087+
"in": "query",
3088+
"required": true,
3089+
"schema": {
3090+
"type": "string"
3091+
},
3092+
"description": "Asset code (e.g. XLM)"
3093+
}
3094+
],
3095+
"responses": {
3096+
"200": {
3097+
"description": "Threshold removed",
3098+
"content": {
3099+
"application/json": {
3100+
"schema": {
3101+
"$ref": "#/components/schemas/ApiEnvelope"
3102+
}
3103+
}
3104+
}
3105+
},
3106+
"400": {
3107+
"description": "userId or asset required",
3108+
"content": {
3109+
"application/json": {
3110+
"schema": {
3111+
"$ref": "#/components/schemas/ApiError"
3112+
},
3113+
"examples": {
3114+
"QueryValidationError": {
3115+
"$ref": "#/components/examples/QueryValidationError"
3116+
}
3117+
}
3118+
}
3119+
}
3120+
},
3121+
"404": {
3122+
"description": "No override found for asset",
3123+
"content": {
3124+
"application/json": {
3125+
"schema": {
3126+
"$ref": "#/components/schemas/ApiError"
3127+
}
3128+
}
3129+
}
3130+
},
3131+
"500": {
3132+
"description": "Internal error",
3133+
"content": {
3134+
"application/json": {
3135+
"schema": {
3136+
"$ref": "#/components/schemas/ApiError"
3137+
}
3138+
}
3139+
}
3140+
}
3141+
}
3142+
}
3143+
},
28653144
"/api/queue/health": {
28663145
"get": {
28673146
"tags": [
@@ -3203,6 +3482,18 @@
32033482
"weekly"
32043483
],
32053484
"description": "Delivery mode for notifications: immediate (per-event), daily digest, or weekly digest."
3485+
},
3486+
"priceAlertThresholds": {
3487+
"type": "object",
3488+
"additionalProperties": {
3489+
"type": "number",
3490+
"minimum": 1
3491+
},
3492+
"description": "Per-asset price alert threshold overrides keyed by asset code (e.g. XLM).",
3493+
"example": {
3494+
"XLM": 7,
3495+
"BTC": 3
3496+
}
32063497
}
32073498
}
32083499
}

0 commit comments

Comments
 (0)