|
1752 | 1752 | } |
1753 | 1753 | } |
1754 | 1754 | }, |
| 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 | + }, |
1755 | 1830 | "/api/risk/metrics/{portfolioId}": { |
1756 | 1831 | "get": { |
1757 | 1832 | "tags": [ |
|
2862 | 2937 | } |
2863 | 2938 | } |
2864 | 2939 | }, |
| 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 | + }, |
2865 | 3144 | "/api/queue/health": { |
2866 | 3145 | "get": { |
2867 | 3146 | "tags": [ |
|
3203 | 3482 | "weekly" |
3204 | 3483 | ], |
3205 | 3484 | "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 | + } |
3206 | 3497 | } |
3207 | 3498 | } |
3208 | 3499 | } |
|
0 commit comments